如何在Powershell中有效地填充数组 [英] How to fill an array efficiently in Powershell

查看:43
本文介绍了如何在Powershell中有效地填充数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Powershell 尽快用相同的整数值填充动态数组.
Measure-Command 显示我的系统需要 7 秒才能填满它.
我当前的代码(剪下)看起来像:

I want to fill up a dynamic array with the same integer value as fast as possible using Powershell.
The Measure-Command shows that it takes 7 seconds on my system to fill it up.
My current code (snipped) looks like:

$myArray = @()
$length = 16385
for ($i=1;$i -le $length; $i++) {$myArray += 2}  

(完整代码可以在 gist.github.com超级用户)

考虑到 $length 可以改变.但为了更好的理解,我选择了固定长度.

Consider that $length can change. But for better understanding I chose a fixed length.

问:如何加快此 Powershell 代码的运行速度?

Q: How do I speed up this Powershell code?

推荐答案

您可以重复数组,就像处理字符串一样:

You can repeat arrays, just as you can do with strings:

$myArray = ,2 * $length

这意味着»取具有单个元素2的数组并重复它$length次,产生一个新数组.«.

This means »Take the array with the single element 2 and repeat it $length times, yielding a new array.«.

请注意,您不能真正使用它来创建多维数组,因为以下原因:

Note that you cannot really use this to create multidimensional arrays because the following:

$some2darray = ,(,2 * 1000) * 1000

只会创建 1000 个对内部数组的引用,使它们无法用于操作.在这种情况下,您可以使用混合策略.我用过

will just create 1000 references to the inner array, making them useless for manipulation. In that case you can use a hybrid strategy. I have used

$some2darray = 1..1000 | ForEach-Object { ,(,2 * 1000) }

过去,但低于性能测量表明

in the past, but below performance measurements suggest that

$some2darray = foreach ($i in 1..1000) { ,(,2 * 1000) }

会更快.

一些性能测量:

Command                                                  Average Time (ms)
-------                                                  -----------------
$a = ,2 * $length                                                 0,135902 # my own
[int[]]$a = [System.Linq.Enumerable]::Repeat(2, $length)           7,15362 # JPBlanc
$a = foreach ($i in 1..$length) { 2 }                             14,54417
[int[]]$a = -split "2 " * $length                                24,867394
$a = for ($i = 0; $i -lt $length; $i++) { 2 }                    45,771122 # Ansgar
$a = 1..$length | %{ 2 }                                         431,70304 # JPBlanc
$a = @(); for ($i = 0; $i -lt $length; $i++) { $a += 2 }       10425,79214 # original code

通过 Measure-Command 运行每个变体 50 次,每次都具有相同的 $length 值,并对结果求平均值.

Taken by running each variant 50 times through Measure-Command, each with the same value for $length, and averaging the results.

实际上,位置 3 和 4 有点令人惊讶.显然,在一个范围内 foreach 而不是使用普通的 for 循环要好得多.

Position 3 and 4 are a bit of a surprise, actually. Apparently it's much better to foreach over a range instead of using a normal for loop.

生成上图的代码:

$length = 16384

$tests = '$a = ,2 * $length',
         '[int[]]$a = [System.Linq.Enumerable]::Repeat(2, $length)',
         '$a = for ($i = 0; $i -lt $length; $i++) { 2 }',
         '$a = foreach ($i in 1..$length) { 2 }',
         '$a = 1..$length | %{ 2 }',
         '$a = @(); for ($i = 0; $i -lt $length; $i++) { $a += 2 }',
         '[int[]]$a = -split "2 " * $length'

$tests | ForEach-Object {
    $cmd = $_
    $timings = 1..50 | ForEach-Object {
        Remove-Variable i,a -ErrorAction Ignore
        [GC]::Collect()
        Measure-Command { Invoke-Expression $cmd }
    }
    [pscustomobject]@{
        Command = $cmd
        'Average Time (ms)' = ($timings | Measure-Object -Average TotalMilliseconds).Average
    }
} | Sort-Object Ave* | Format-Table -AutoSize -Wrap

这篇关于如何在Powershell中有效地填充数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆