А АTuesday, 19 December 2017

Время выполнения скрипта в Powershell.

Всем привет.

Иногда в скриптах PowerShell требуется определить время, затраченное на выполнение команды. В PowerShell есть несколько способов решения этой задачи. К примеру в .NET есть специальный класс StopWatch, который можно использовать как секундомер для измерения времени, потраченного на выполнение задачи.

Класс StopWatch входит в пространство имен System.Diagnostics и у него есть статический метод StartNew. С помощью этого метода создадим новый экземпляр класса StopWatch, сохраним его в переменную и выведем свойства и методы нашего таймера:
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch | Get-Member

Здесь нас интересуют методы Start и Stop, отвечающие за запуск и остановку таймера и свойство Elapsed, показывающее прошедшее время.

Теперь создадим вот такой скрипт, который ищет в некоторой папке все файлы с расширением txt и записывает полученный результат в файл:
$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch.Start() #Запуск таймера
Get-Childitem -Path E:\TMP\audit -Filter ?*.txt? -Recurse | Out-File e:\files1.txt
$watch.Stop() #Остановка таймера
Write-Host 'Время выполнения 1' $watch.Elapsed

Запустим его и посмотрим, что выдаст секундомер. Как видите, выполнение задачи заняло  3674526 долей секунды.

Еще для измерения времени выполнения задачи в PowerShell есть командлет Measure-Command. Этот командлет берет команду(блок команд), указанную в фигурных скобках, выполняет ее внутри себя и в качестве результата выдает время, затраченное на выполнение. Вот так будет выглядеть наш скрипт с использованием Measure-Command:
Measure-Command -Expression {Get-Childitem -Path E:\TMP\audit -Filter ?*.txt? -Recurse | Out-File e:\files2.txt}

Measure-Command выдает результат в не очень удобном виде. Для того, чтобы получить более наглядное представление, можно воспользоваться методом ToString:
$time2 = Measure-Command -Expression {Get-Childitem -Path E:\TMP\audit -Filter ?*.txt? -Recurse | Out-File e:\files2.txt}
Write-Host 'Время выполнения 2' $time2.ToString()

В этом случае результат выводится в одну строку, в таком же виде, как и при использовании StopWatch.

Ух ты, а на первый раз результат то на порядок меньший, как в предыдущем примере - всего 269218 долей секунды.

Такая огромная разница в показателях хронометра видна только на малых выборках. Чем больше данных надо обработать тем больше совпадение результатов между Measure-Command и
System.Diagnostics.Stopwatch.

Также следует учесть, что на скорость выполнения скрипта может влиять загруженность системы, скорость сетевого подключения и прочие внешние факторы. Для одной и той же команды, запущенной в разное время результат может заметно различаться. Поэтому для получения более-менее точного результата измерение стоит повторить несколько раз и усреднить итог.

Успехов.

No comments:

Post a Comment

А что вы думаете по этому поводу?

Версия на печать

Популярное