将数组传递给函数非常慢

Ian*_*gan 7 arrays powershell performance

我编写了一个PowerShell脚本,需要在函数之间传递大字节数组.脚本运行速度非常慢.下面的示例代码重现了该问题.它只是将一个10 MiB数组传递给一个不执行任何操作的函数(除了记录消息),并测量调用所需的时间.

function do-nothing
{
    param($foo)
    Write-Verbose -Verbose "in the function"
}

$tenMiB = 10 * 1024 * 1024
$myFoo = New-Object byte[] $tenMiB

Write-Verbose -Verbose "about to do call a function that does nothing..."
$elapsed = Measure-Command -Expression { do-nothing -foo $myFoo }
Write-Verbose -Verbose "doing nothing took $($elapsed.TotalMilliseconds) milliseconds"
Run Code Online (Sandbox Code Playgroud)

我希望这需要几毫秒.在我的家用电脑上,它需要将近3000毫秒,并以100%的速度运行CPU核心.我使用PowerShell 4和PowerShell 5(预生产版本)获得了相同的结果.我的工作PC和服务器也发生了同样的事情.但是,一位同事获得了预期的结果 - 执行几毫秒,CPU使用率最低.

执行时间大致与数组的大小成正比,这对我来说毫无意义.阵列的大小无关紧要.

我想知道数组是否以某种方式被复制.我不认为是这种情况,因为调用GetHashCode()数组会返回函数内部和外部的相同值.

如果数组包装在a中PSCustomObject,并且包装器被传递给函数,则代码将按预期执行.作为一种解决方法,这有点难看,我宁愿在诉诸之前了解正在发生的事情.

有谁能解释这看似奇怪的行为吗?

bri*_*ist 4

我将其作为社区 wiki 发布,旨在成为我们可以发布个人环境和测试结果的地方,因为似乎存在一些重现问题。也许我们可以找出导致这种情况的条件,并从那里确定为什么它在这种情况下很慢。欢迎格式建议/更改。


布莱恩蒂斯特

工作站

  • 硬件(i7)
  • 视窗8.1
  • 电源外壳4.0
  • ISE 和控制台
  • 域已加入
  • byte[]结果:~3,500ms
  • object[]结果:~6,500ms

服务器虚拟机

  • 虚拟机(VMware ESXi)
  • Windows 2012 R2
  • PowerShell 5.0.10514.6(生产预览)
  • 伊势
  • 域已加入
  • byte[]结果:> 7,000ms
  • object[]结果:~100ms

家庭工作站

  • 硬件(i5)
  • Windows 10 内部版本 1511
  • 电源外壳5
  • ISE 和控制台
  • 工作组(无广告)
  • 结果:首次运行 4-6 毫秒,后续运行 < 2 毫秒

埃曼雷苏

  • 电源外壳4
  • 结果:1.8 - 2.4 毫秒

培根块

工作站

  • Windows 7 x64 SP1
  • 域已加入
  • 电源外壳4
  • 结果:100 次执行,平均 1.16ms,最小值 0.67ms,最大值 13.88ms,stddev 1.39ms

虚拟机(ESXi)

  • Windows Server 2012 R2
  • 域已加入
  • 电源外壳4
  • 结果:10 次执行,平均值 4221ms,最小值 4173ms,最大值 4302ms,stddev 38.54ms

安斯加尔·维彻斯

虚拟机(虚拟盒)

  • Windows 2012 R2(普通安装)
    • PowerShell 4
      CLRV 版本:4.0.30319.34014
      内部版本:6.3.9600.16394
    • 结果:~7.5ms
  • Windows 2012 R2(同一虚拟机,已完全修补)
    • PowerShell 4
      CLRV 版本:4.0.30319.34209
      内部版本:6.3.9600.17400
    • 结果:~4000ms

进一步调查显示,该问题是由 2014 年 11 月更新汇总 ( MSKB 3000850 ) 引入的。但不确定收集到的哪个修补程序是真正的罪魁祸首。


节拍乐手

桌面

  • 硬件:Q6600@3.1 GHz/8GB RAM
  • Windows 服务器 2012
  • 工作组(无广告)
  • PowerShell 5 (5.0.10018.0)
  • ISE 和控制台
  • 结果:~5000ms

笔记本电脑

  • 硬件:i3@2.5 GHz/4GB RAM
  • 视窗8.1
  • 加入域的 PC
  • 电源外壳4
  • ISE 和控制台
  • 结果:~6000ms

大卫·布拉班特

  • 电源外壳5
  • Windows 10
  • 结果:< 7 毫秒

苏打柳

  • 硬件(i5)
  • 视窗8.1
  • 工作组(无广告)
  • PowerShell 5.0.10514.6
  • 伊势
  • 结果:> 3500 毫秒

马蒂亚斯·R·杰森

家用笔记本电脑

  • 硬件 (i7-2620M)
  • Windows 10(内部版本 10240)
  • 电源外壳5.0
  • ISE 和控制台
  • byte[]结果:~5,350ms
  • object[]结果:~8,500ms
  • int[]结果:~9,700ms