首页 > 解决方案 > Powershell:将名称和值数组高性能转换为可解析格式 - 我怎样才能使它更快

问题描述

当我希望从 JSON 有效负载创建一个容易/快速的可解析对象/PSCustomObject 时,如何使我的代码性能更高$JSON

我收到的 PAYLOAD 结构的一个示例是:

[
    {
        "name":  "system.enablenetflow",
        "value":  "false"
    },
    {
        "name":  "system.deviceGroupId",
        "value":  "186,3060"
    },
    {
        "name":  "system.prefcollectorid",
        "value":  "144"
    },
    {
        "name":  "system.collectorplatform",
        "value":  "windows"
    }
]

如您所见,它的格式非常烦人。

请注意,我尝试解析的有效负载要大得多,并且数量从 500 个这些名称/值对象到 50000 个不等,而不仅仅是上面列出的 4 个。

################################################# #########################

我的目标

把它变成一个键值对场景,以便以后更容易解析

不是这个

使用 JSON 我必须做$JSON.where({$_.name -eq "system.enablenetflow"}).value

是的

我希望最终状态是$obj我创建的新变量会让我得到值$obj."system.enablenetflow"

################################################# #########################

我目前的尝试非常慢

我做了以下事情:

  1. 创建一个空 PSCustomObject 并将其保存为变量$obj
  2. $JSON对遍历 JSON 数组的变量执行了 foreach 方法
  3. 添加成员$obj,将“名称”设置为 PropertyName,将“值”设置为 PropertyValue

这是我的代码示例:

$obj = [PSCustomObject] @{}
$json.foreach({
   $thisitem = $_
   $obj | Add-member -NotePropertyName $($thisitem.name) -NotePropertyValue $($thisitem.name)
})

我怎样才能让它更快?

标签: jsonpowershellparsingoptimizationpscustomobject

解决方案


# Sample input JSON.
$json =  @'
[
    {
        "name":  "system.enablenetflow",
        "value":  "false"
    },
    {
        "name":  "system.deviceGroupId",
        "value":  "186,3060"
    },
    {
        "name":  "system.prefcollectorid",
        "value":  "144"
    },
    {
        "name":  "system.collectorplatform",
        "value":  "windows"
    }
]
'@

# Initialize the (ordered) result hashtable.
$result = [ordered] @{}

# Note: In PowerShell (Core) 7+, add -AsHashTable to the ConvertFrom-Json
#       call for additional performance gain, combined with -AsArray,
#       in which case you don't need the `(...)` around the call anymore.
foreach ($element in (ConvertFrom-Json $json)) {
  $result[$element.name] = $element.value
}

上面创建了一个(有序的)哈希表而不是一个[pscustomobject]实例 - 特别是如果后者是通过调用迭代构造的。Add-Member

哈希表比[pscustomobject]实例更轻量且构建速度更快。

使用foreach循环而不是处理管道ConvertFrom-Json中的输出via也可以加快处理速度。ForEach-Object

PowerShell 允许您将熟悉的点表示法也用于哈希表;因此,例如,在运行上述内容后,您将获得:

PS> $result.'system.collectorplatform'
windows

如果您确实需要$result成为一个[pscustomobject]实例,您可以简单地将完全填充的哈希表转换为该类型:

PS> $obj = [pscustomobject] $result; $obj.'system.collectorplatform'
windows

推荐阅读