2016-10-19 9 views
0

以下のコードを参照してください.2つのスクリプトの唯一の違いは、2つ目のスクリプトブロックがないことです。そのためにパフォーマンスが大幅に向上します。Powershell Perfomance with Where-Object?

これには理由がありますか?もう一つはパワーシェルにネイティブですか?

多くのスクリプトを複数の類似のブロックで実行していますが、このような簡単なパフォーマンスの向上を得るための合理的な答えが必要です。なぜ、スクリプトブロックの除外がWhere-Object(エイリアス?)が突然パフォーマンスを適度なマージンでカットしましたか?

PS C:\Scripts> $a = 1..15 | % { 
    Measure-Command { 
     $G = Get-ADGroup -Filter * 
     1..3 | % { 
      $G | ? {$_.Name -eq "TestGroup$($_)"} 
     } 
    } 
} 

$b = 1..15 | % { 
    Measure-Command { 
     $G = Get-ADGroup -Filter * 
     1..3 | % { 
      $G | ? Name -eq "TestGroup$($_)" 
     } 
    } 
} 

($a.TotalMilliseconds | Measure -Average).Average 
($b.TotalMilliseconds | Measure -Average).Average 

283.479413333333 
212.57384 
+0

実際には、その差ははるかに大きいです。これを分離するには、 '$ G'割り当てを測定から外し、' 1.e5'のようなより大きな内部ループを使用します。 – wOxxOm

+1

混乱を避けるために、むしろ混乱を避けるために、 "パフォーマンスをカット"しません_。それは「実行時間を削減する」か「パフォーマンスを向上させる」のいずれかです。一つを選ぶ。 :-) –

答えて

0

のPowerShell 3.0導入Where-Object(別名:Where?)スクリプトブロックせずに直接プロパティを確認することができます。

スクリプトブロックが実行されるとき、PowerShellは他の言語と同様に、新しい実行コンテキストを作成します。これはインタープリタ言語では非常に高価です。スクリプトブロック古い表記法を使用する

唯一の理由は、次のとおり

  • PS1/PS2互換コードを持っています。複雑なチェックを行うには
  • です。
  • チェック自体のほかに何かをする。
  • あなたのコードについては

、両方のスニペットは、他の場所でscriptblocksを使用し、パイプライン(それはforeach声明より5-10x遅くなります)、および不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 
    } 
} 
関連する問題