Reputation: 2398
I've got a script which indexes information from our equipment. To store and analyze the information I've created a class:
Add-Type @'
public class CPObject
{
public int id;
public string name;
public string displayname;
public string classname;
public string ip;
public string netmask;
public string ManagementServer;
}
'@
Then when I run the script I've been planning to go through the object class to translate name to IP with the following function:
Function NameToIP {
Param([int]$id=0, [string]$name="")
$CPObject = $CPNetworkObjects | Where-Object { $_.id -eq $id -and $_.name -eq $name }
If($CPObject.count -eq 1){
$CPObject.ip
} else {
""
}
}
It works, but it's terribly slow as the $CPNetworkObjects contains over 12 000 elements of the type CPObject.
I want to speed this up. Is there any way to index an array to make the search more efficient or is the only solution to try to lessen the number of objects used?
Kind regards, Patrik
Upvotes: 0
Views: 1397
Reputation: 68341
If any give combination of id plus name is unique, you can speed up a name-to-ip resolution by building a lookup table:
$NameToIP = @{}
Foreach ($Object in $Array) { $NameToIP["$($Object.id)_$($Object.Name)"] = $Object.ip }
Function NameToIP {
Param([int]$id=0, [string]$name="")
$NameToIP["$id_$name"]
}
Upvotes: 3
Reputation: 141
Is there any way to index an array to make the search more efficient
First of all, I don't know a thing about powershell so I won't be able to give you code samples.
If either the id or name is unique, you should try to remove this unique field from your CPObject and use it as the key for your hash map, and have your CPObject as the value returned by the hash table.
You should try to sort your array using the name and/or the id You can go from O(n) time complexity O(log(n)) when looking for a name to
Hope this helped,
Upvotes: 0
Reputation: 26170
maybe you could use a pscustomobject instead of a class ? searching an array of 15000 simple objects doesnt seem too long :
PS>(1..15000) |%{
>>> $res+=new-object pscustomobject -property @{"id"=$_;name=(get-random)}
>>> }
PS> measure-command -expression {$res |?{$_.id -eq 14999 -and $_.name -eq 513658722}}
takes 802ms
Upvotes: 1