【问题标题】:Powershell Merge 2 lists PerformancePowershell Merge 2 列出了性能
【发布时间】:2017-09-07 08:50:33
【问题描述】:

我在 Powershell 中有两个包含大量数据的列表:

  • $Byods 包含大约 5000 个项目的 MAC 和用户名
  • $DHCPLeases 包含大约 3000 项的 MAC 和 IP

我想创建一个新列表,其中包含 Byods 列表前导的用户名和 IP,并且 IP 是从 DHCPleases 中找到的,仅包含找到匹配项的记录(左连接?)

我创建了一个 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
    }
}

【问题讨论】:

  • 开始:将 $userbyods += 替换为 list.add() 之类的东西(首先创建一个新列表)。使用 += 在每次迭代时复制数组。第二:您可以在步骤之间用秒表检查性能并查看哪些步骤需要“长时间”运行。

标签: performance list powershell join


【解决方案1】:

这里可以进行一些改进。首先,不要使用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】:

    在循环中附加到数组很慢。只需在循环中输出您的自定义对象并在变量$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
        }
    }
    

    【讨论】:

    • 哇,非常感谢你们!这将脚本缩短到仅 2 秒!
    【解决方案3】:

    我没有您的列表,但我想知道我的 Join-Object cmdlet 对此有何表现。
    命令应该是这样的:

    $Byods | LeftJoin $DHCPLeases Mac
    

    我已经在性能上付出了一些努力,但由于它是一个通用的解决方案,它可能无法与这里给出的特定解决方案竞争......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2021-04-24
      相关资源
      最近更新 更多