我在Powershell中有两个包含大量数据的列表:
我想创建一个包含Byods列表所在的用户名和IP的新列表,并且从DHCPleases中找到IP,只包含找到匹配的记录(左连接?)
我创建了一个foreach循环,完成了这项工作。但是,它需要花费大量的时间来完成(> 30分钟)。
我相信这可以更快。任何人吗?
$UserByods = @()
foreach ($lease in $DHCPLeases)
{
$MAC = [string]$lease.MAC
$UserByod = @()
$UserByod = $Byods | where {$_.MAC -eq $MAC}
if (($UserByod | measure).count -eq 1) {
$ByodIP = New-Object -TypeName PSObject
$ByodIP | Add-Member -Name 'User' -MemberType Noteproperty -Value $UserByod.Username
$ByodIP | Add-Member -Name 'IP' -MemberType Noteproperty -Value $lease.IP
$UserByods += $ByodIP
}
}
答案 0 :(得分:4)
在循环中追加数组很慢。只需在循环中输出自定义对象,并在变量$UserByods
中收集循环输出。列表中的线性读取也很慢。更好地从$Byods
构建哈希表,以便您可以通过其MAC地址查找设备。
$tbl = @{}
$Byods | ForEach-Object { $tbl[$_.MAC] = $_ }
$UserByods = foreach ($lease in $DHCPLeases) {
New-Object -TypeName PSObject -Property @{
'User' = $tbl[$lease.MAC].Username
'IP' = $lease.IP
}
}
答案 1 :(得分:4)
这里可以进行一些改进。首先,不要使用Add-Member
来构造对象,它会比预先指定属性慢得多。
您还希望避免在集合上使用加法运算符(+=
),因为它会导致调整基础数组的大小,这是一个非常耗费内存的操作。
最后使用散列表进行MAC相关,它比循环遍历所有5000个条目3000次(这是...| Where {...}
基本上做的那样)要快得多:
$BYODTable = $Byods |ForEach-Object -Begin { $table = @{} } -Process { $table[$_.MAC] = $_.Username } -End { return $table }
$UserByods = foreach ($lease in $DHCPLeases)
{
$MAC = [string]$lease.MAC
if ($BYODTable.ContainsKey($MAC)) {
New-Object -TypeName PSObject -Property @{
User = $BYODTable[$MAC]
IP = $lease.IP
}
}
}
答案 2 :(得分:0)
我没有您的列表,但我想知道我的Join-Object
cmdlet如何执行此操作
命令应该是这样的:
$Byods | LeftJoin $DHCPLeases Mac
我已经在性能方面付出了一些努力,但由于它是一般解决方案,它可能无法与此处给出的具体解决方案竞争......