Note that there are some explanatory texts on larger screens.

plurals
  1. POCompare-Object PowerShell performance and Operation VS Loop
    primarykey
    data
    text
    <p>I was looking at <a href="https://stackoverflow.com/questions/16657743/how-can-i-compare-two-arrays-removing-similar-items-without-iterating-through">this question</a> where the OP wanted to know how to compare items in two arrays without looping through each array.</p> <p>The command given was:</p> <pre><code>$array3 = @(Compare-Object $array1 $array2 | select -Expand InputObject </code></pre> <p>My question is two-fold:</p> <p>One, does this actually avoid iterating through the arrays in any form? Or does it simply obfuscate the operation from the user by doing it behind the scenes.</p> <p>Two, as far as performance goes is this the best method for comparing objects? It appears to me it is actually significantly slower.</p> <p>I made a real crude test:</p> <pre><code>$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 </code></pre> <p>And my times came out:</p> <p>ForEach-Object: 00:00:00.0030001</p> <p>Compare-Object: 00:00:00.0030002</p> <hr> <h2>Edit</h2> <p>I updated the script to make it more fair, and it essentially evened out the times.</p> <p>So what is the behind the scenes difference between Compare-Object and a traditional loop? Am I correct in assuming none?</p> <hr> <h2>Edit 2</h2> <p>I found this code using the decompiler:</p> <pre><code>internal int Compare(ObjectCommandPropertyValue first, ObjectCommandPropertyValue second) { if (first.IsExistingProperty &amp;&amp; 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) &amp;&amp; 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); } </code></pre> <p>I have traced it around as best as I can, and I believe these are the two worker threads. It appears Compare-Object actually only does a 1 &lt;==> 1 check down the list. Am I missing something here?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload