如何最好地加快 powershell 处理时间(比较对象)

Ton*_*ony 2 powershell

我有一个 powershell 脚本,用于Compare-Object比较/比较 MD5 校验和列表...我怎样才能加快速度?它已经运行了几个小时了!

$diffmd5 = 
(Compare-Object -ReferenceObject $localmd5 -DifferenceObject $remotefilehash |
 Where-Object { ($_.SideIndicator -eq '=>') } | 
Select-Object -ExpandProperty InputObject)
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 5

Compare-Object方便,但确实慢;完全避免管道对于最大化性能也很重要。

我建议使用一个实例,它支持在一组无序[1][System.Collections.Generic.HashSet[T]值中进行高性能查找:[2]

# Two sample arrays
$localmd5 = 'Foo1', 'Bar1', 'Baz1'
$remotefilehash = 'foo1', 'bar1', 'bar2', 'baz1', 'more'

# Create a hash set from the local hashes.
# Make lookups case-*insensitive*.
# Note: Strongly typing the input array ([string[]]) is a must.
$localHashSet = [System.Collections.Generic.HashSet[string]]::new(
  [string[]] $localmd5,
  [System.StringComparer]::OrdinalIgnoreCase
)

# Loop over all remote hashes to find those not among the local hashes.
$remotefilehash.Where({ -not $localHashSet.Contains($_) })
Run Code Online (Sandbox Code Playgroud)

以上产生了 Collection 'bar2', 'more'

请注意,如果区分大小写的查找就足够了(这是默认值(对于字符串元素)),则简单的强制转换足以构造哈希集:

$localHashSet = [System.Collections.Generic.HashSet[string]] $localmd5
Run Code Online (Sandbox Code Playgroud)

注意:您后来的反馈指出,这$remotefilehash是键值对的哈希表(类似)集合,而不是单纯的文件哈希字符串的集合,其中存储哈希字符串。在这种情况下:

  • 要查找不同的哈希字符串(请注意.Keys获取键值数组的属性访问):

    $remotefilehash.Keys.Where({ -not $localHashSet.Contains($_) })
    
    Run Code Online (Sandbox Code Playgroud)
  • 查找那些键不在哈希集中的键值对.GetEnumerator()(注意枚举所有条目(键值对)的调用):

    $remotefilehash.GetEnumerator().Where({ -not $localHashSet.Contains($_.Key) })
    
    Run Code Online (Sandbox Code Playgroud)

或者,如果输入集合 (a) 大小相同并且 (b) 具有相应的元素(即,一个集合中的元素 1 应与另一个集合中的元素 1 进行比较,依此类推),则使用Compare-Objectwith -SyncWindow 0,如图所示在js2010的有用答案中,后续.SideIndicator过滤可能是一种选择;为了加速操作,-PassThru应该使用 switch,它放弃将不同的对象包装在[pscustomobject]实例中(.SideIndicator然后将属性作为NoteProperty成员直接添加到不同的对象)。


[1] 有一个用于维护排序的相关类型System.Collections.Generic.SortedSet[T]但是 - 从 .NET 6 开始 -没有内置类型用于维护输入顺序中的值,尽管您可以通过派生来创建自己的类型[System.Collections.ObjectModel.KeyedCollection[TKey, TItem]]

[2] 请注意,与哈希表不同,哈希没有与其条目关联的值。如果您愿意的话,哈希集是“所有键” - 它支持的只是测试是否存在key == value。