我正在涉足 Powershell,对 .NET 完全陌生。
我正在运行一个以空哈希表开头的 PS 脚本。哈希表将增长到至少 15,000 到 20,000 个条目。哈希表的键是字符串形式的电子邮件地址,值是布尔值。 (我只需要跟踪我是否看到过电子邮件地址。)
到目前为止,我一直在一次增加哈希表的一个条目。我检查以确保键值对尚不存在(PS 在这种情况下会出错),然后添加该对。
这是我们正在讨论的代码部分:
...
if ($ALL_AD_CONTACTS[$emailString] -ne $true) {
$ALL_AD_CONTACTS += @{$emailString = $true}
}
...
我想知道从 PowerShell 或 .NET 的角度来看,如果您提前知道该哈希表会很大,例如 15,000 到 20,000 个条目或更多,是否可以做一些事情来优化该哈希表的性能。
Thanks!
我使用进行了一些基本测试Measure-Command,使用一组 20 000随机词.
各个结果如下所示,但总而言之,通过首先分配一个具有单个条目的新哈希表来添加到一个哈希表的效率非常低:) 尽管选项 2 到 5 之间有一些小的效率提升,但总的来说,它们都执行了差不多。
如果让我选择,我可能会倾向于选项 5,因为它简单(只需一个Add每个字符串调用),但我测试的所有替代方案似乎都是可行的。
$chars = [char[]]('a'[0]..'z'[0])
$words = 1..20KB | foreach {
$count = Get-Random -Minimum 15 -Maximum 35
-join (Get-Random $chars -Count $count)
}
# 1) Original, adding to hashtable with "+=".
# TotalSeconds: ~800
Measure-Command {
$h = @{}
$words | foreach { if( $h[$_] -ne $true ) { $h += @{ $_ = $true } } }
}
# 2) Using sharding among sixteen hashtables.
# TotalSeconds: ~3
Measure-Command {
[hashtable[]]$hs = 1..16 | foreach { @{} }
$words | foreach {
$h = $hs[$_.GetHashCode() % 16]
if( -not $h.ContainsKey( $_ ) ) { $h.Add( $_, $null ) }
}
}
# 3) Using ContainsKey and Add on a single hashtable.
# TotalSeconds: ~3
Measure-Command {
$h = @{}
$words | foreach { if( -not $h.ContainsKey( $_ ) ) { $h.Add( $_, $null ) } }
}
# 4) Using ContainsKey and Add on a hashtable constructed with capacity.
# TotalSeconds: ~3
Measure-Command {
$h = New-Object Collections.Hashtable( 21KB )
$words | foreach { if( -not $h.ContainsKey( $_ ) ) { $h.Add( $_, $null ) } }
}
# 5) Using HashSet<string> and Add.
# TotalSeconds: ~3
Measure-Command {
$h = New-Object Collections.Generic.HashSet[string]
$words | foreach { $null = $h.Add( $_ ) }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)