我有一个用c#编写的SSIS脚本任务,我希望它移植到powershell作为脚本使用。c#版本的运行时间为12.5秒,但powershell版本的运行时间为100.5秒,几乎慢了一个数量级。我正在处理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#脚本任务中获得的相同性能?
除非在PowerShell中实际使用c#,否则无法获得与c#相当的PowerShell性能。Add-Type
cmdlet允许编译一些通常微不足道的c#片段,并直接从脚本调用它们。如果性能是一个问题,并且由于某些原因c#程序集的使用是不可能的,那么我会这样做。
示例如下:http://go.microsoft.com/fwlink/?LinkID=135195
前段时间我看到一个问题,并试图回答它-看看http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/da36e346-887f-4456-b908-5ad4ddb2daa9。坦率地说,使用PowerShell的性能损失是如此之大,以至于对于耗时的任务,我总是选择c#或Add-Type
,就像@Roman建议的那样。
您正在将c#转换为Powershell,这可能不是在所有情况下都理想。是的,使用c#会提高你的性能,但这并不意味着你不能得到与Powershell比较的性能。
你应该尝试利用Powershell管道中的"流"。
例如:
gc file.txt | ?{ process.....} | %{process...} | out-file out.txt
会更快,因为对象一旦可用就会沿着管道传递。
你可以尝试使用Get-Content
和流水线等效吗?