Powershell – превратности производительности


Не так давно я публиковал скрипт для расшифровки опции 82 из DHCP лога Windows Server 2012/R2. Эта заготовка требовала обертки для полноценного использования на практике. Такой скрипт был написан, и в процессе его отладки и оптимизации выяснились некоторые интересные факты о производительности Powershell.

Лог файл DHCP в лога Windows Server 2012/R2 имеет оригинальный формат: в начале идет текст с описанием опций и только потом основная часть лога почти в формате CSV. (Почему «почти» — об этом в другой раз.)

Поэтому для считывания файла журнала первоначально была использована конструкция, которая пропускала первые 33 описательные строки:

    
    $content = Get-Content $logfileName | Select-Object -Skip 33 | 
            # Convert from CSV to PSObject
            ConvertFrom-Csv -Header $Header | 
            # Filter only "Renew" rows and "Assign" rows
            ? {$_.Id -eq "11" -or $_.Id -eq "10"} |
            % { $_.sortDateTime = ([datetime]"$($_.Date) $($_.Time)").ToString("yyyyMMddHHmmss"); $_ } |
            % { if ( $_.sortDateTime -gt $script:UnuqueRows[$_.'MAC Address'].sortDateTime ) 
       { … }
}

Эта конструкция в моём примере выполнялась за 22 секунды для всего набора журналов (14 штук).

Только на само считывание

    $content = Get-Content $logfileName | Select-Object -Skip 33 | 

затрачивалось 8 секунд! Учитывая очень скромный размер журналов, участвующих в тесте, это было явно расточительно.

Тут появилась идея попробовать командлет Select-String, чтобы убить сразу трёх зайцев: во-первых, избавиться от явно медленной конструкции Select -Skip 33, во-вторых, сразу отфильтровать только нужные строки (ID=10 и ID=11) и как следствие этого избавиться от лишних вызовов ConvertFrom-Csv и в-третьих, всё вместе уменьшало длину конвейера на три шага.

В результате только считывание:

    $content = Select-String -Path $logfileName -Pattern "^(10|11)," | 

стало занимать 2 секунды вместо 8 – в четыре раза увеличилось быстродействие!

Вся конструкция стала выглядеть так:

    $content = Select-String -Path $logfileName -Pattern "^(10|11)," | Select -ExpandProperty Line |
            # Convert from CSV to PSObject
            ConvertFrom-Csv -Header $Header | 
            % { $_.sortDateTime = ([datetime]"$($_.Date) $($_.Time)").ToString("yyyyMMddHHmmss"); $_ } |
            % { if ( $_.sortDateTime -gt $script:UnuqueRows[$_.'MAC Address'].sortDateTime ) 
       { … }
}

Оказалось, что последние для шага конвейера можно заменить одним. Финальный вариант:

    $content = Select-String -Path $logfileName -Pattern "^(10|11)," | Select -ExpandProperty Line |
            # Convert from CSV to PSObject
        ConvertFrom-Csv -Header $Header | 
         % { $_.sortDateTime = ([datetime]"$($_.Date) $($_.Time)").ToString("yyyyMMddHHmmss")
               if ( $_.sortDateTime -gt $script:UnuqueRows[$_.'MAC Address'].sortDateTime ) 
   { … }
}

показал прекрасное быстродействие: 7 секунд вместо первоначальных 22-х – почти в три раза возросла производительность скрипта даже без оптимизации основной функции расшифровки DHCP опции 82!

Эффект оптимизации будет ещё более ощутим на DHCP журналах большого размера.

Реклама

комментария 4

  1. […] Powershell – превратности производительности […]

  2. […] скрипта Powershell. Даже небольшие изменения в скрипте (см. Powershell – превратности производительности) способны уменьшить время выполнения скрипа в […]

  3. Замена ^(10|11), на ^1[01], должна дать еще процентов 10

    • Замерил оба варианта — разницы не получилось, к сожалению :-( хотя хотелось.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: