具有Where-Object的Powershell Perfomance?

时间:2016-10-19 10:27:35

标签: performance powershell

参见下面的代码,两个脚本中唯一的区别是第二个脚本中缺少脚本块,并且由于它而导致性能显着提高。

这有什么理由吗? PowerShell是另一个原生的吗?

我正在做大量的脚本,其中许多脚本都有多个相似的块,并且想要获得一个合理的答案,如何获得这样的简单性能提升,那么为什么在{中排除一个脚本块? {1}}(别名Where-Object)突然降低了性能?

?

1 个答案:

答案 0 :(得分:0)

PowerShell 3.0引入了Where-Object(别名:Where?),可以在没有脚本块的情况下直接检查属性。

执行脚本块时,PowerShell与任何其他语言一样,会创建一个新的执行上下文,并且在解释语言中非常昂贵。

对脚本块使用旧表示法的唯一原因是:

  • 拥有与PS1 / PS2兼容的代码;
  • 执行复杂的检查;
  • 除了检查本身之外还要做点什么。

至于您的代码,两个代码段都使用其他地方的脚本块,流水线操作(它比foreach语句慢5-10倍),并且不必要地测量Get-ADGroup时间,因此我们可以优化它甚至更多:

$group = Get-ADGroup -Filter *
$c = foreach ($i in 1..15) {
    Measure-Command {
        foreach ($j in 1..3) {
            $filtered = foreach ($g in $group) { if ($g.Name -eq "TestGroup$($j)") { $g } }
        }
    }
}

有时,通过准备数据可以获得更大的收益。例如,如果在循环中重复检查某些对象数组以查看它是否具有某个属性值,那么最好将数组转换为具有基于该属性值的键的哈希表:

# index by somefield
$lookup = @{}
foreach ($element in $array) { $lookup[$element.somefield] = $element }

# use the indexed lookup table
foreach ($element in $anotherarray) {
    $existingElement = $lookup[$element.somefield]
    if ($existingElement) {
        # do something 
    }
}