性能调优PowerShell文本处理

时间:2011-08-03 11:04:31

标签: c# performance powershell

我有一个用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())}
    }   
}

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

3 个答案:

答案 0 :(得分:2)

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

请参阅此处的示例:http://go.microsoft.com/fwlink/?LinkID=135195

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

例如:

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

当对象一旦可用就传递给管道,它会更快。

您可以使用Get-Content和流水线操作试用等效文件吗?