2

我在看这个问题,OP 想知道如何比较两个数组中的项目而不循环每个数组。

给出的命令是:

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

我的问题有两个:

一,这真的避免了以任何形式遍历数组吗?或者它只是通过在幕后进行操作来混淆用户的操作。

二,就性能而言,这是比较对象的最佳方法吗?在我看来,它实际上要慢得多。

我做了一个真正的粗略测试:

$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);
    }

我已经尽可能地追踪它,我相信这是两个工作线程。看起来 Compare-Object 实际上只执行 1 <==> 1 检查列表。我在这里错过了什么吗?

4

0 回答 0