Powershell - Benchmark Command

Powershell comes with a cmdlet called "Measure-Command" that can execute a block of commands and measure how long it takes to run. It's analogous to the unix "time" command.

What if you want to run something a number of times and take the average?

Here's a powershell function to do just that: function measure_runs { param ( [int]$numberRuns = $(throw "numberRuns is required"), [ScriptBlock]$beforeRun = $null, [ScriptBlock]$run = {} ) $times = @() for($i=1;$i -le $numberRuns;$i++) { Write-Host -NoNewline ("[" + "{0,4}" -f $i + " / " + "{0,4}" -f $numberRuns + "] ") if($beforeRun -ne $null) { Write-Host -NoNewline ("(Preparing... ) ") &$beforeRun | Out-Null } Write-Host -NoNewline ("Running...") $seconds = (Measure-Command $run).TotalSeconds $times += $seconds Write-Host -NoNewline (" {0,14:N4} seconds" -f $seconds) Write-Host } $times | Measure-Object -average | Select-Object Average }


Specify the number of runs, the command to run and optionally a command to run before each run to be measured. (The before command is not included in the time.)

measure_runs -numberRuns N -run { cmd } [-beforeRun { cmd }]

Example: PS D:\Development\jboss-seam-2.1.2> measure_runs -numberRuns 5 -beforeRun { ant clean } -run { ant } [ 1 / 5] (Preparing... ) Running... 34.1149 seconds [ 2 / 5] (Preparing... ) Running... 34.4194 seconds [ 3 / 5] (Preparing... ) Running... 34.5866 seconds [ 4 / 5] (Preparing... ) Running... 34.5777 seconds [ 5 / 5] (Preparing... ) Running... 34.2238 seconds Average ------- 34.38447462

The hardest part was figuring out how to supress the newline when outputting so that the progress could be displayed incrementally. The default Write-Output cmdlet doesn't let you do that, however the Write-Host cmdlet does using to "-noNewline" option.

Comments