具有初始容量的Powershell哈希表

具有初始容量的Powershell哈希表,powershell,hashtable,Powershell,Hashtable,我想知道如何在powershell中声明具有初始容量的哈希表。我知道我希望它有多大,但我必须在循环中给它赋值 比如: $hashtable = @{} (100) 很好地说明了为什么不需要指定初始容量: 但是,请注意,预先指定容量通常不会为您赢得多少内存或运行时间;它已经实现了慷慨的动态大小调整,如果你猜错了,好处基本上消失了 如果确实需要指定初始容量: 向他表示感谢 由于PowerShell的哈希表对于键查找始终不区分大小写,因此不幸的是,[hashtable]::new(100)不起作用,

我想知道如何在powershell中声明具有初始容量的哈希表。我知道我希望它有多大,但我必须在循环中给它赋值

比如:

$hashtable = @{} (100)
很好地说明了为什么不需要指定初始容量:

但是,请注意,预先指定容量通常不会为您赢得多少内存或运行时间;它已经实现了慷慨的动态大小调整,如果你猜错了,好处基本上消失了

如果确实需要指定初始容量:

向他表示感谢

由于PowerShell的哈希表对于键查找始终不区分大小写,因此不幸的是,
[hashtable]::new(100)
不起作用,因为默认设置是创建区分大小写的哈希表

因此,需要使用允许指定键相等比较方法的
[System.Collections.Hashtable]
构造函数重载,以便指定区分区域性、不区分大小写的相等比较器,以匹配v6.1-[1]中PowerShell的常用哈希表行为:

PetSerAl提供了以下替代方案:

$hashtable = [System.Collections.Specialized.CollectionsUtil]::CreateCaseInsensitiveHashtable(100)
注意:在v6.2+PowerShell中,现在使用顺序字符串比较器(
[StringComparer]::OrdinalIgnoreCase

此外,正如PetSerAl指出的,PowerShell v6.1-缓存当前会话的密钥相等比较器-因此忽略当前区域性的会话内更改。如果您想模拟这种-可疑-行为,PetSerAl提供以下命令:

$hashtable = [hashtable]::new(100,
 [hashtable].GetProperty(
   'EqualityComparer',
   [System.Reflection.BindingFlags]'NonPublic, Instance'
 ).GetValue(@{}))
尽管使用反射来访问非公共属性,但这种方法应该是安全的,因为目标属性的访问修饰符是受保护的,这意味着它与派生的公共类有“契约”,并且不会消失


请注意,优化哈希表的另一种方法是指定其加载因子,并且还有用于指定该因子的构造函数重载

起自(加强调):

哈希表的容量用于根据负载因子计算哈希表存储桶的最佳数量。容量会根据需要自动增加

负载系数是元件与铲斗的最大比率。较小的负载系数意味着以增加内存消耗为代价加快查找速度

当实际负载系数达到指定的负载系数时,铲斗数量将自动增加到最小素数,该素数大于当前铲斗数量的两倍


[1] 请注意,在许多上下文中,PowerShell对字符串操作使用不变区域性,但哈希表似乎是个例外-请参阅和。

显示PowerShell哈希表构造函数中CurrentCultureInoRecase的用法,现在显示序号(不区分大小写)比较的用法。

[hashtable]::新(100)
或(旧版本)
新对象System.Collections.hashtable 100
。但是,请注意,预先指定容量通常不会为您赢得多少内存或运行时间;它已经实现了慷慨的动态大小调整,如果你的猜测是关闭的好处基本上蒸发。我会更好奇,你为什么要这样做。为了防止有更好的方法来完成你的目标,PetSerAl-answer再次更新,请看一看。考虑到通常的文化不变理念,你知道为什么在PowerShell中哈希表是文化敏感的吗?可能一开始是出于偶然,然后为了兼容性而保持这种方式。与cmdlet参数的字符串转换相同。
$hashtable = [hashtable]::new(100,
 [hashtable].GetProperty(
   'EqualityComparer',
   [System.Reflection.BindingFlags]'NonPublic, Instance'
 ).GetValue(@{}))