简体   繁体   中英

Powershell: High Performing conversion of Name and Value Array into Parseable format - How can I make this Faster

How can I make my code a lot more performant when I wish to make an easily/fast parseable object/PSCustomObject from a JSON payload $JSON ?

An example of the structure of the PAYLOAD I receive is:

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

As you can see its in a very annoying format.

Note that the payloads I attempt to parse are much larger and variable in count from 500 of these Name/Value objects to 50000, rather than just the 4 listed above.

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

MY GOAL

To have this turn into a key:value pair scenario for easier parsing later

NOT This :

With the JSON I have to do $JSON.where({$_.name -eq "system.enablenetflow"}).value

YES THIS :

I want the end state to be that the new variable $obj I create will let me get the value with $obj."system.enablenetflow"

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

MY CURRENT ATTEMPT THAT IS SUPER SLOW

I did the following:

  1. Create an Empty PSCustomObject and saved it as variable $obj
  2. Did a foreach method on the $JSON variable which iterated through the JSON Array
  3. Add-Member to $obj with setting the 'name' as PropertyName and 'value' as PropertyValue

Heres a sample of my code:

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

HOW CAN I MAKE THIS FASTER?

# 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
}

The above creates an (ordered) hashtable instead of a [pscustomobject] instance - especially if the latter are iteratively constructed via Add-Member calls.

Hashtables are lighter-weight and faster to construct than [pscustomobject] instances.

Using a foreach loop rather than processing the ConvertFrom-Json output in a pipeline via ForEach-Object also speeds up processing.

PowerShell allows you to use the familiar dot notation also with hashtables; so, for instance, after running the above, you'll get:

PS> $result.'system.collectorplatform'
windows

If you do need $result to be a [pscustomobject] instance, you can simply cast the fully populated hashtable to that type:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM