【问题标题】:Performance tuning powershell text processing性能调优 powershell 文本处理
【发布时间】:2011-08-03 11:04:31
【问题描述】:

我有一个用 C# 编写的 SSIS 脚本任务,我希望将它移植到 powershell 以用作脚本。 C# 版本运行时间为 12.1s,但 powershell 版本需要 100.5s,几乎慢了一个数量级。我正在处理 11 个文本文件 (csv),每种格式大约有 3-4 百万行:

<TICKER>,<DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>
AUDJPY,20010102,230100,64.30,64.30,64.30,64.30,4
AUDJPY,20010102,230300,64.29,64.29,64.29,64.29,4
<snip>

我只想将内容写入一个新文件,其中列的日期为 20110101 或更晚。这是我的 C# 版本:

    private void ProcessFile(string fileName)
    {
        string outfile = fileName + ".processed";
        StringBuilder sb = new StringBuilder();
        using (StreamReader sr = new StreamReader(fileName))
        {
            string line;
            int year;
            while ((line = sr.ReadLine()) != null)
            {
                year = Convert.ToInt32( sr.ReadLine().Substring(7, 4));
                if (year >= 2011)
                {
                    sb.AppendLine(sr.ReadLine());
                }
            }
        }

        using (StreamWriter sw = new StreamWriter(outfile))
        {
            sw.Write(sb.ToString());
        }
    }

这是我的 powershell 版本:

foreach($file in ls $PriceFolder\*.txt) {
    $outFile = $file.FullName + ".processed"
    $sr = New-Object System.IO.StreamReader($file)
    $sw = New-Object System.IO.StreamWriter($outFile)
    while(($line = $sr.ReadLine() -ne $null))
    {       
        if ($sr.ReadLine().SubString(7,4) -eq "2011") {$sw.WriteLine($sr.ReadLine())}
    }   
}

如何在 Powershell 中获得与在 SSIS 中的 C# 脚本任务中获得相同的性能?

【问题讨论】:

  • 只是好奇,你打算在两个循环示例中调用 ReadLine() 三次吗?看起来它会跳过一行,匹配第二行,打印第三行,然后重复。

标签: c# performance powershell


【解决方案1】:

除非您在 PowerShell 中实际使用 C#,否则您无法获得与 C# 相媲美的 PowerShell 性能。 Add-Type cmdlet 允许编译一些通常很简单的 C# sn-ps 并直接从脚本中调用它们。如果性能是一个问题并且由于某些原因无法使用 C# 程序集,那么我会这样做。

在此处查看示例:http://go.microsoft.com/fwlink/?LinkID=135195

【讨论】:

    【解决方案2】:

    前段时间我看到一个问题并试图回答它 - 看看http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/da36e346-887f-4456-b908-5ad4ddb2daa9。坦率地说,使用 PowerShell 时的性能损失是如此之大,以至于对于耗时的任务,我总是会按照 @Roman 的建议选择 C# 或 Add-Type

    【讨论】:

      【解决方案3】:

      您正在将 C# 转换为 Powershell,这在所有情况下可能并不理想。是的,使用 C# 可以提高性能,但这并不意味着您无法获得与 Powershell 相比的性能。

      您应该尝试利用 Powershell 管道中的“流”。

      例如:

      gc file.txt | ?{ process.....} | %{process...} | out-file out.txt
      

      对象一可用就会沿着管道传递,这样会更快。

      您可以尝试使用 Get-Content 和流水线的等效方法吗?

      【讨论】:

        猜你喜欢
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 2014-03-01
        • 2014-10-14
        • 2016-06-26
        • 1970-01-01
        • 2017-02-11
        • 1970-01-01
        相关资源
        最近更新 更多