2

OPが各配列をループせずに2つの配列内のアイテムを比較する方法を知りたがっているこの質問を見ていました。

与えられたコマンドは次のとおりです。

$array3 = @(Compare-Object $array1 $array2 | select -Expand InputObject

私の質問は 2 つあります。

1つ目は、これは実際に配列の反復処理を何らかの形式で回避することですか? それとも、舞台裏で行うことで、ユーザーからの操作を単に難読化しますか。

2 つ目は、パフォーマンスに関する限り、これはオブジェクトを比較するための最良の方法ですか? 私には、実際にはかなり遅いようです。

私は本当の大雑把なテストを行いました:

$Array1 = @("1","2","Orchid","Envy","Sam","Map Of the World","Short String","s","V","DM","qwerty","1234567891011")
$Array2 = @("Bob", "Helmet", "Jane")

$Date1 = Get-Date
$Array2 | ForEach-Object `
    {
    if ($Array1 -contains $_){}

    }
$Date2 = Get-Date
$Time1 = [TimeSpan]$Date2.Subtract($Date1)
Write-Host $Time1

$Date1 = Get-Date
$Array3 = @(Compare-Object $Array1 $Array2)
$Date2 = Get-Date
$Time2 = [TimeSpan]$Date2.Subtract($Date1)
Write-Host $Time2

そして私の時間が出てきました:

ForEach-オブジェクト: 00:00:00.0030001

比較オブジェクト: 00:00:00.0030002


編集

スクリプトを更新してより公平にすると、本質的に時間が均等になりました。

では、Compare-Object と従来のループの舞台裏での違いは何でしょうか? 何もないと仮定するのは正しいですか?


編集 2

逆コンパイラを使用してこのコードを見つけました:

internal int Compare(ObjectCommandPropertyValue first, ObjectCommandPropertyValue second)
    {
      if (first.IsExistingProperty && second.IsExistingProperty)
        return this.Compare(first.PropertyValue, second.PropertyValue);
      if (first.IsExistingProperty)
        return -1;
      return second.IsExistingProperty ? 1 : 0;
    }

    public int Compare(object first, object second)
    {
      if (ObjectCommandComparer.IsValueNull(first) && ObjectCommandComparer.IsValueNull(second))
        return 0;
      PSObject psObject1 = first as PSObject;
      if (psObject1 != null)
        first = psObject1.BaseObject;
      PSObject psObject2 = second as PSObject;
      if (psObject2 != null)
        second = psObject2.BaseObject;
      try
      {
        return LanguagePrimitives.Compare(first, second, !this.caseSensitive, (IFormatProvider) this.cultureInfo) * (this.ascendingOrder ? 1 : -1);
      }
      catch (InvalidCastException ex)
      {
      }
      catch (ArgumentException ex)
      {
      }
      return string.Compare(((object) PSObject.AsPSObject(first)).ToString(), ((object) PSObject.AsPSObject(second)).ToString(), !this.caseSensitive, this.cultureInfo) * (this.ascendingOrder ? 1 : -1);
    }

できる限りトレースしましたが、これらは 2 つのワーカー スレッドであると思います。Compare-Object は、実際にはリストを 1 <==> 1 チェックするだけのようです。ここで何か不足していますか?

4

0 に答える 0