2014-02-12 25 views
1

這可能是一個哲學問題,但我想知道以下兩個條目從速度和效率的角度來看有何不同。在PowerShell中我有2個物體看起來像這樣的:Where-Object或Compare-Object哪個更好?

$ObjectA = @() 
1..10 | foreach-object{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectA += $obj 
} 

$ObjectB = @() 
5..15 | foreach-0bject{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectB += $obj 
} 

現在,我想的是存在於兩個對象。我可以通過2種方法中的其中一種來做。

解決方案1:

$ObjectA | foreach-object{ 
     $ind = $_ 
     $matching = $ObjectB | where {$_ -eq $ind} 
     if (![string]::IsNullOrEmpty($matching)){ 
      ##do stuff with the match 
     } 
    } 

解決方案2:

$matches = Compare-Object $ObjectA $ObjectB -Property index | where {$_.SideIndicator -eq '=='} -PassThru 
    $matches | foreach-object { 
     ##do stuff with the matches. 
    } 

我的問題是,當我的對象數組變得非常大,其人會(30K +)是從一個更好的解決方案性能角度?我不知道Compare-Object cmdlet如何在內部工作,所以我真的不知道。或者沒有關係?

在此先感謝。

+2

您是否嘗試過使用測量命令? – mjolinor

+0

最好採用更大的樣本集。並嘗試不同的場景,如集合中的隨機分佈。 – EBGreen

回答

2

正如@Knows Not Multi指出的那樣,Compare-Object通常比自己迭代收集和比較對象提供更好的性能。但另一個答案不能使用-ExcludeDifferent參數,而是遍歷比較對象輸出。這意味着要對SideIndicator屬性進行許多無用的字符串比較。爲了獲得最佳性能,以及更簡單的代碼,只需使用-IncludeEqual-ExcludeDifferent

$ObjectA = @() 
1..10000 | %{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectA += $obj 
} 

$ObjectB = @() 
1000..7000 | %{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectB += $obj 
} 

# Iterating over the result of Compare-Object takes 2.6 seconds. 
Measure-Command { $matches_where_eq = Compare-Object $ObjectA $ObjectB -Property index -IncludeEqual | where {$_.SideIndicator -eq '=='} ; echo $matches_where_eq.count } 

# Using -IncludeEqual and -ExcludeDifferent takes 2.1 seconds (80% of previous). 
Measure-Command { $matches_ed_ie = Compare-Object $ObjectA $ObjectB -Property index -ExcludeDifferent -IncludeEqual; echo $matches_ed_ie.Count } 
0

這將構建一個數組中的正則表達式搜索,然後對另一個數組執行正則表達式匹配。

解決方案3:

[regex]$RegMatch = '(' + (($ObjectA |foreach {[regex]::escape($_)}) –join "|") + ')' 
$ObjectB -match $RegMatch 

可能要拋出一些邏輯的,要建立正則表達式出來的小數據集,然後運行較大的一組反對爲了加快速度,但我很確定這將是最快的。

1

即使您使用大小爲10000的數據集,也可以輕鬆看到比較對象的速度更快。

我修改了代碼,使其上的PowerShell 3.0

cls 
$ObjectA = @() 
1..10000 | %{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectA += $obj 
} 

$ObjectB = @() 
1000..7000 | %{ 
    $obj = New-Object System.Object 
    $obj | Add-Member -Type NoteProperty -Name index -Value $_ 
    $ObjectB += $obj 
} 

Measure-Command { 
    $count = 0 
    $matches = Compare-Object $ObjectA $ObjectB -Property index -IncludeEqual | where {$_.SideIndicator -eq '=='} 
} 

echo $matches.length 
echo $matches.Count 

Measure-Command { 
    $count = 0 
    $ObjectA | %{ 
     $ind = $_ 
     $matching = $ObjectB | where {$_.Index -eq $ind.Index} 
     if (![string]::IsNullOrEmpty($matching)){ 
      $count = $count + 1 
     } 
    } 
    echo $count 
} 

在不到5秒的比較對象的回報工作....但其他的方法只是被永遠困。

+0

完美。謝謝。 :) – AnthonyBCodes