Заметки о Windows и других программных продуктах Microsoft...

Секундомер для PowerShell скрипта

Секундомер для PowerShell скрипта

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

Класс StopWatch входит в пространство имен System.Diagnostics и у него есть статический метод StartNew. С помощью этого метода создадим новый экземпляр класса StopWatch, сохраним его в переменную и выведем свойства и методы нашего ″таймера″:

$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch | Get-Member

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

свойства и методы класса StopWatch

 

Теперь создадим вот такой скрипт, который ищет в папке Windows все файлы с расширением txt и записывает полученный результат в файл:

$watch = [System.Diagnostics.Stopwatch]::StartNew()
$watch.Start() #Запуск таймера
Get-Childitem -Path C:\Windows -Filter ″*.txt″ -Recurse | Out-File C:\Files\files.txt
$watch.Stop() #Остановка таймера
Write-Host $watch.Elapsed #Время выполнения

Запустим его и посмотрим, что выдаст секундомер. Как видите, выполнение задачи заняло чуть больше 3 секунд (3,2).

вывод времени выполнения с помощью StopWatch

 

Еще для измерения времени выполнения задачи в PowerShell есть командлет Measure-Command. Этот командлет берет команду\блок команд, указанную в фигурных скобках, выполняет ее внутри себя и в качестве результата выдает время, затраченное на выполнение. Вот так будет выглядеть наш скрипт с использованием Measure-Command:

Measure-Command -Expression {Get-Childitem -Path C:\Windows -Filter ″*.txt″ -Recurse | Out-File C:\Files\files.txt}

Результат такой же, как и в предыдущем примере — 3,2 секунды.

вывод времени выполнения с помощью Measure-Command

 

Measure-Command выдает результат в не очень удобном виде. Для того, чтобы получить более наглядное представление, можно воспользоваться методом ToString:

$time = Measure-Command -Expression {Get-Childitem -Path C:\Windows`
-Filter ″*.txt″ -Recurse | Out-File C:\Files\files.txt}
$time.ToString()

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

выполнения с помощью Measure-Command в строку

 

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

 
 
Комментарии

Я тихо фигею, у меня таймер отрабатывает но files.txt пуст.

Андрей

команды
$watch = [System.Diagnostics.Stopwatch]::StartNew()
и
$watch.Start() #Запуск таймера
почти дублируют друг друга, первая создает счетчик и запускает его, а вторая запускает ещё раз, но при этом отчет времени ведется все равно от первого и тогда $watch.Start() просто лишняя, но правильнее будет даже скорее всего использовать такую конструкцию:
$watch = [System.Diagnostics.Stopwatch]::New() в любом месте, как правило в начале скрипта

а уже где надо посчитать время
$watch.Start()

$watch.Stop()

Ответить