gpt4 book ai didi

powershell - 从函数返回字节数组时内存消耗高

转载 作者:行者123 更新时间:2023-12-03 14:32:30 29 4
gpt4 key购买 nike

我正在尝试下载一个 10MB 的文件并将其存储为一个数组以供进一步处理。

使用直接调用 (New-Object System.Net.WebClient).DownloadData("<url>") 时一切正常.但是如果我将它包装在一个函数中并将调用结果返回给 WebClient::DownloadData 内存占用增加到 500mb 左右。

我使用的功能:

function My-Download {
param (
[Parameter(Mandatory = $True, Position = 1)] [String] $UrlCode
)
(New-Object System.Net.WebClient).DownloadData($UrlCode)
}
$x = My-Download("https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_1280_10MG.mp4")

我将它包装在函数中的原因是我还在返回数据之前对数据进行了额外的处理,但即使是这个小例子也说明了这个问题。

调用 $x = (New-Object System.Net.WebClient).DownloadData("https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_1280_10MG.mp4")结果为 83MB:

direct call memory consumption

调用上面的函数会产生 500MB:

wrapper function memory consumption

如此高的内存使用率的原因是什么,我可以做些什么来优化它?

Powershell 版本:
Major  Minor  Build  Revision
----- ----- ----- --------
5 1 17134 407

最佳答案

[System.Net.WebClient]类型的 .DownloadData()方法返回一个字节数组( [byte[]] )。

  • 如果您将调用该方法的输出直接分配给变量 , 变量按原样接收该字节数组 .
  • 相比之下,如果对该方法的调用用于从函数 产生隐式输出, [byte[]] 数组的元素被一一送入管道 (逐字节)。
    管道背后的设计意图是启用流式处理、逐个对象处理而不是收集所有结果优先的行为,这将执行速度换成内存节流、逐个、作为输出变为可用加工。

  • 将函数的输出分配给一个变量,然后使 PowerShell 在常规 [object[]] 中隐式收集各个输出对象(在本例中为字节)。大批。
    换句话说:原来的 [byte[]]数组首先被枚举,后来才被收集到另一个数组中,尽管是 [object[]] -typed one - 这在您的场景中显然是不必要且效率低下的。
    两种选择退出此隐式枚举的方法 :
  • 您可以使用 代替隐式输出概念明确 Write-Output -NoEnumerate 调用以抑制输出数组(集合)的枚举:
  • Write-Output -NoEnumerate (New-Object System.Net.WebClient).DownloadData($UrlCode)
  • 一个更晦涩但更简洁更快的替代方案 是将隐式输出与 结合起来辅助单元素包装器数组 ,这会导致 PowerShell 仅枚举包装器数组,将包装过的数组传递通过,如 PetSerAl在对该问题的评论中建议:
  • , (New-Object System.Net.WebClient).DownloadData($UrlCode)
  • ,是 PowerShell 的数组构造运算符( "comma operator" ),并且以其一元形式将 RHS 包装在单元素数组(类型 [object[]] )中。
  • 关于powershell - 从函数返回字节数组时内存消耗高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56925009/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com