我想知道您如何在Powershell中以初始容量声明哈希表。我知道我希望它有多大,但是我必须在循环中为其分配值。
类似这样:
$hashtable = @{} (100)
答案 0 :(得分:2)
JeroenMostert很好地说明了为什么您不需要指定初始容量的原因:
请注意,尽管预先指定容量通常不会在内存或运行时方面为您带来多大好处;它已经实现了大幅度的动态调整大小,并且如果您的猜测不成立,那么好处基本上就会消失。
如果确实需要指定初始容量:
向PetSerAl求助。
由于PowerShell的哈希表对于键查找总是不区分大小写,因此[hashtable]::new(100)
不能 起作用,因为默认情况下是创建案例-敏感哈希表。
因此,需要使用[System.Collections.Hashtable]
构造函数重载,该重载允许指定键相等比较方法,以便您指定区分文化,不区分大小写的相等比较器匹配PowerShell的通常哈希表行为 [1] :
# PSv5+ syntax
$hashtable = [hashtable]::new(100, [StringComparer]::CurrentCultureIgnoreCase)
# PSv4- syntax
$hashtable = New-Object hashtable 100, ([StringComparer]::CurrentCultureIgnoreCase)
PetSerAl提供以下选择:
$hashtable = [System.Collections.Specialized.CollectionsUtil]::CreateCaseInsensitiveHashtable(100)
另外,正如PetSerAl指出的那样, PowerShell 缓存当前会话的键相等比较器-因此,当前文化的会话内更改被忽略了。 > 。如果要模拟这种可疑的行为,PetSerAl提供以下命令:
$hashtable = [hashtable]::new(100,
[hashtable].GetProperty(
'EqualityComparer',
[System.Reflection.BindingFlags]'NonPublic, Instance'
).GetValue(@{}))
尽管使用反射来访问非公共属性,但是这种方法应该是安全的,因为目标属性的访问修饰符为protected
,这意味着它具有一个与派生的公共类“签订合同”,不会消失。
请注意,优化哈希表的另一种方法是指定其负载因子,并且还存在用于指定该因子的构造函数重载。
来自the docs(添加了重点):
哈希表的容量用于根据负载因子计算哈希表存储桶的最佳数量。容量会根据需要自动增加。
负载系数是元素与存储桶的最大比率。较小的加载因子意味着更快的查找速度,但会增加内存消耗。
当实际负载系数达到指定的负载系数时,铲斗数将自动增加到最小素数,该最小素数大于当前铲斗数的两倍。
[1]请注意,在许多情况下,PowerShell使用不变文化进行字符串操作,但哈希表似乎是一个例外-请参见this GitHub issue和this answer 。
The source code揭示了在PowerShell哈希表构造函数中使用CurrentCultureIgnoreCase
。