Powershell 5.1的性能问题

发布于 2025-01-24 11:43:50 字数 2422 浏览 1 评论 0原文

我有一个powershell脚本,可以读取和解析文本文件。该文件被读取到内存中,然后按行处理。

当我从PowerShell 4.0转换为5.1时,脚本变慢了约10倍(60秒而不是6秒)。 有人知道如何使脚本运行速度更快吗?

#------------------------------------------------------------------------
# Function GetNextLine.
# Read next text line from input text array into variables.
# Parameter:
#    $inTextArr[]: (in)    Input text array
#    $linenr     : (inout) line number, will be increased
#    $line       : (out)   read text line
#    $line2      : (out)   read text line without leading and trailing spaces
#    $s1         : (out)   first word read in text line
#------------------------------------------------------------------------
function GetNextLine {
   param (
       [ref]$inTextArr
      ,[ref]$linenr
      ,[ref]$line
      ,[ref]$line2
      ,[ref]$s1
   ) 
   $linenr.value++
   $line.value = $inTextArr.value[$linenr.value-1]
   $line2.value= $line.value.trim()
   $s1.value   = $line2.value.split(" ")[0]
} # function GetNextLine
#------------------------------------------------------------------------

#------------------------------------------------------------------------
# Function ParseMifFile.
# Parse input text array.
#------------------------------------------------------------------------
function ParseMifFile { 
   param( 
      [ref]$inTextArr
   )

   # Initialize output parameters and variables.
   [int]$linenr  = 0
   [string]$line = ""
   [string]$line2= ""
   [string]$s1   = ""
   
   # (Extract. The orginal script has lots of GetNextLine calls.)
   GetNextLine -inTextArr ([ref]$inTextArr.value) -linenr ([ref]$linenr) -line ([ref]$line) -line2 ([ref]$line2) -s1 ([ref]$s1)
   while ($line -cne "# End of MIFFile") {
      GetNextLine -inTextArr ([ref]$inTextArr.value) -linenr ([ref]$linenr) -line ([ref]$line) -line2 ([ref]$line2) -s1 ([ref]$s1)     
   }
} # function ParseMifFile
#------------------------------------------------------------------------

# Prepare a large text array for performance test below (just for test purpose, instead of reading in the input file).
$inTextArr= @()
for ($i= 1; $i -lt 50000; $i++) {
   $inTextArr= $inTextArr + "This is a line from the input file"
}
$inTextArr= $inTextArr + "# End of MIFFile"

# Performance test of function ParseMifFile.
measure-command {
   ParseMifFile -inTextArr ([ref]$inTextArr) 
   # Very slow in Powershell 5.1.17763.2803 (60 sec) compared to Powershell 4.0 (6 sec) 
}

I have a powershell script that reads and parses a text file. The file is read into memory and then processed line by line.

When I switched from Powershell 4.0 to 5.1, the script became about 10 times slower (60 seconds instead of 6 seconds).
Does anyone have an idea how I can make the script run faster?

#------------------------------------------------------------------------
# Function GetNextLine.
# Read next text line from input text array into variables.
# Parameter:
#    $inTextArr[]: (in)    Input text array
#    $linenr     : (inout) line number, will be increased
#    $line       : (out)   read text line
#    $line2      : (out)   read text line without leading and trailing spaces
#    $s1         : (out)   first word read in text line
#------------------------------------------------------------------------
function GetNextLine {
   param (
       [ref]$inTextArr
      ,[ref]$linenr
      ,[ref]$line
      ,[ref]$line2
      ,[ref]$s1
   ) 
   $linenr.value++
   $line.value = $inTextArr.value[$linenr.value-1]
   $line2.value= $line.value.trim()
   $s1.value   = $line2.value.split(" ")[0]
} # function GetNextLine
#------------------------------------------------------------------------

#------------------------------------------------------------------------
# Function ParseMifFile.
# Parse input text array.
#------------------------------------------------------------------------
function ParseMifFile { 
   param( 
      [ref]$inTextArr
   )

   # Initialize output parameters and variables.
   [int]$linenr  = 0
   [string]$line = ""
   [string]$line2= ""
   [string]$s1   = ""
   
   # (Extract. The orginal script has lots of GetNextLine calls.)
   GetNextLine -inTextArr ([ref]$inTextArr.value) -linenr ([ref]$linenr) -line ([ref]$line) -line2 ([ref]$line2) -s1 ([ref]$s1)
   while ($line -cne "# End of MIFFile") {
      GetNextLine -inTextArr ([ref]$inTextArr.value) -linenr ([ref]$linenr) -line ([ref]$line) -line2 ([ref]$line2) -s1 ([ref]$s1)     
   }
} # function ParseMifFile
#------------------------------------------------------------------------

# Prepare a large text array for performance test below (just for test purpose, instead of reading in the input file).
$inTextArr= @()
for ($i= 1; $i -lt 50000; $i++) {
   $inTextArr= $inTextArr + "This is a line from the input file"
}
$inTextArr= $inTextArr + "# End of MIFFile"

# Performance test of function ParseMifFile.
measure-command {
   ParseMifFile -inTextArr ([ref]$inTextArr) 
   # Very slow in Powershell 5.1.17763.2803 (60 sec) compared to Powershell 4.0 (6 sec) 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生一个溪 2025-01-31 11:43:50

不确定为什么在5.1中慢了为什么您将整个内容传递给每个NextLine功能调用。

“有人知道如何使脚本运行速度更快吗?”

这是怎么回事?它应该获取您的文件内容,并将每行传递到一个类似的对象中。

$MyContentArray = Get-Content -Path "[C:\My\FilePath]" | ForEach-Object {
    [PSCustomObject]@{
        liner = $i++
        line = $_
        line2 = $_.trim()
        s1 = ($_.trim()).split(" ")[0]
    }
}

pscustomObject

Not sure on why slower in 5.1 You're passing the entire content to each nextline function call, though.

"Does anyone have an idea how I can make the script run faster?"

How's the time on this? It should get your file content and pass each line into a similar object.

$MyContentArray = Get-Content -Path "[C:\My\FilePath]" | ForEach-Object {
    [PSCustomObject]@{
        liner = $i++
        line = $_
        line2 = $_.trim()
        s1 = ($_.trim()).split(" ")[0]
    }
}

Get-Content

PSCustomObject

爱本泡沫多脆弱 2025-01-31 11:43:50

在我看来,使用参考参数传递文本数组到该函数需要大量时间。

作为替代方案,我已经创建了一个自定义对象,如坦斯塔夫(Tanstaafl)上一个答案中所建议的,其中包含有关当前读取文件行的​​所有信息。
该程序更快(1.5秒)而不是60秒。

function GetNextLine {
   param (
      [PSCustomObject]$linePtrO     
   ) 
   $linePtrO.linenr++
   $linePtrO.line = $linePtrO.inTextArr[$linePtrO.linenr-1]
   $linePtrO.line2= $linePtrO.line.trim()
   $linePtrO.s1   = $linePtrO.line2.split(" ")[0]
} # function GetNextLine

function ParseMifFile {
   param (
      [string]$inFileNameStr
   )
   $linePtrO = [PSCustomObject] @{
        inTextArr = get-content -path $inFileNameStr -encoding utf8
        linenr    = 0
        line      = ""
        line2     = ""
        s1        = ""
   }     
   # (Extract. The orginal script has lots of GetNextLine calls.)
   GetNextLine -linePtrO $linePtrO

   while ($linePtrO.line -cne "# End of MIFFile") {
      GetNextLine -linePtrO $linePtrO    
   }
} # function ParseMifFile

$fileNameStr= "C:\mypath\myfile"
ParseMifFile -inFileNameStr $fileNameStr

It seems to me that passing a text array using a reference parameter to the function takes a lot of time.

As an alternative I have created a custom object as suggested in the previous answer by tanstaafl, which contains all the information about the currently read file line.
The program is so much faster (1.5 sec) instead of 60 sec.

function GetNextLine {
   param (
      [PSCustomObject]$linePtrO     
   ) 
   $linePtrO.linenr++
   $linePtrO.line = $linePtrO.inTextArr[$linePtrO.linenr-1]
   $linePtrO.line2= $linePtrO.line.trim()
   $linePtrO.s1   = $linePtrO.line2.split(" ")[0]
} # function GetNextLine

function ParseMifFile {
   param (
      [string]$inFileNameStr
   )
   $linePtrO = [PSCustomObject] @{
        inTextArr = get-content -path $inFileNameStr -encoding utf8
        linenr    = 0
        line      = ""
        line2     = ""
        s1        = ""
   }     
   # (Extract. The orginal script has lots of GetNextLine calls.)
   GetNextLine -linePtrO $linePtrO

   while ($linePtrO.line -cne "# End of MIFFile") {
      GetNextLine -linePtrO $linePtrO    
   }
} # function ParseMifFile

$fileNameStr= "C:\mypath\myfile"
ParseMifFile -inFileNameStr $fileNameStr
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文