我正在尝试创建一个相当大的哈希表数组,其中许多数据是完全随机的或从列表中随机选择的。
这是我的当前代码
$ArrayData = @()
$ArrayDataRows = 150000
foreach ($i in 1..$ArrayDataRows) {
$thisobject = [PSCustomObject] @{
Number = $i
Place = Get-Random -InputObject NJ, UT, NY, MI, PA, FL, AL, NM, CA, OK, TX, CO, AZ
Color = Get-Random -InputObject red, yellow, blue, purple, green, white, black
Zone = (Get-Random -InputObject $([char[]](65..90)) -Count 10) -join ""
Group = Get-Random -InputObject @(1..20)
}
$ArrayData += $thisobject
}
但我注意到的是,这似乎并不有效。完成15万行总共需要25分钟。
我这里还没有发布一些其他代码,该代码测量了每个实例花费了多长时间,并估计了每个实例到其先前实例的平均值。最初,它为我提供了总计450秒的估计时间,对于前3k个项目,每个实例平均为0.002,但后来它一直缓慢地爬升到平均速度的0.016或8倍。
如何在获得相同数据的同时优化和/或提高效率?
最佳答案
[编辑-您未制作哈希表数组。您正在制作PSCustomObject
项数组。 [*笑*]
标准数组是固定大小的对象。看看$ArrayData.IsFixedSize
对此进行确认。 [咧嘴]
因此,当您在标准数组上使用+=
时,powershell会创建一个新的,单项较大的数组,将旧的复制到新的数组中,最后添加新的条目。当项目数量和尺寸“很小”时,它很快,但是随着数量/尺寸的增加,它变得越来越慢(越来越慢)。
有两种常见的解决方案...
.Add()
方法的集合类型人们不常用
ArrayList
(不推荐使用)和Generic.List
。当添加到第一个时,它会输出一个索引号,因此即使它不被弃用,我也不会使用它。 [咧嘴] 您可以使用
$Results = foreach ($Thing in $Collection) {Do-Stuff}
,脚本块的输出将保留在RAM中,直到循环完成。然后将其全部填充到$Results
集合中。 第二是最快的。
如果构建后无需更改集合的大小,请使用2nd方法。否则使用第一个。
以速度为例,您的代码(包含15,000个项目)在我的系统上运行39秒。使用“发送到输出”技术需要24秒。
请记住,随着数组变大,速度变慢将继续恶化。我不愿意等待15万次迭代。
这是我的演示代码...
$ArrayDataRows = 15e3
$PlaceList = 'NJ, UT, NY, MI, PA, FL, AL, NM, CA, OK, TX, CO, AZ'.Split(',').Trim()
$ColorList = 'red, yellow, blue, purple, green, white, black'.Split(',').Trim()
$UC_LetterList = [char[]](65..90)
$GroupList = 1..20
(Measure-Command -Expression {
$ArrayData = foreach ($i in 1..$ArrayDataRows) {
[PSCustomObject] @{
Number = $i
Place = Get-Random -InputObject $PlaceList
Color = Get-Random -InputObject $ColorList
Zone = -join (Get-Random -InputObject $UC_LetterList -Count 10)
Group = Get-Random -InputObject $GroupList
}
}
}).TotalMilliseconds
# total ms = 24,390
关于arrays - Powershell-创建大量哈希表的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55465559/