Настройка производительности PowerShell для обработки текста - PullRequest
2 голосов
/ 03 августа 2011

У меня есть задача сценария служб SSIS, написанная на C #, и я хочу, чтобы она была перенесена в powershell для использования в качестве сценария. Версия C # работает на 12.1 с, но версия 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, какую я могу получить в своей задаче C # Script в SSIS?

Ответы [ 3 ]

2 голосов
/ 03 августа 2011

Вы не можете получить производительность PowerShell, сравнимую с C #, если вы на самом деле не используете C # прямо в PowerShell. Командлет Add-Type позволяет компилировать некоторые обычно тривиальные фрагменты C # и вызывать их прямо из скриптов. Если производительность является проблемой, и использование сборок C # по каким-либо причинам невозможно, я бы пошел по этому пути.

Смотрите примеры здесь: http://go.microsoft.com/fwlink/?LinkID=135195

1 голос
/ 03 августа 2011

Вы переводите C # в Powershell, который может быть не идеальным во всех случаях. Да, использование C # даст вам улучшенную производительность, но это не значит, что вы не сможете получить сравнительную производительность и с Powershell.

Вы должны попытаться использовать преимущества потоковой передачи в конвейерах Powershell.

Например, что-то вроде:

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

Быстрее, поскольку объекты передаются по конвейеру, как только они становятся доступными.

Можете ли вы попробовать эквивалент, используя Get-Content и конвейер?

1 голос
/ 03 августа 2011

Некоторое время назад я увидел вопрос и попытался на него ответить - посмотрите на http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/da36e346-887f-4456-b908-5ad4ddb2daa9. Честно говоря, снижение производительности при использовании PowerShell было настолько огромным, что для трудоемких задач я всегда выбирал либо C #, либо Add-Type как предложил @Roman.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...