PowerShell Performance measurement
Measure-Command tells you how long a block takes. Wrap the thing you suspect, run it a few times, and compare.
Documentation: Microsoft Learn
Overview
There are two traps. First, Measure-Command discards output, so it is for timing rather than getting results. Second, one run is not a measurement. Startup effects, caching and other work on the machine move the number around, so run it several times and look at the spread.
The patterns that actually cost time in PowerShell are predictable. Appending to an array with += rebuilds the whole array on every iteration, which turns a loop into quadratic work; use a List or let the pipeline collect for you. Filtering after retrieval instead of at the source pulls data you throw away, which is why -Filter on a cmdlet beats Where-Object afterwards. And calling a remote command inside a loop pays connection setup on every pass.
A stopwatch is the alternative when you want both the timing and the results, or when you want to time part of a longer operation.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$sum = 0
foreach ($n in 1 .. 10000) { $sum += $n }
$sw.Stop()
[pscustomobject]@{
Sum = $sum
Elapsed_ms = $sw.ElapsedMilliseconds }- Stage 1$sw
Positional values or no named parameters
An example to inspect
Preview the example. Sign in for the full lesson and activities.
$sw = [System.Diagnostics.Stopwatch]::StartNew()
$sum = 0
foreach ($n in 1 .. 10000) { $sum += $n }
$sw.Stop()
[pscustomobject]@{
Sum = $sum
Elapsed_ms = $sw.ElapsedMilliseconds }What happens
A Stopwatch is started, the loop runs, then it is stopped. Building the result object gives you the answer and the timing together, which Measure-Command cannot do. Try the same loop with $list += $n against a growing array and the elapsed number climbs sharply, which is the += problem made visible.
Worth remembering
- Measure-Command times a block and throws away its output.
- Run several times; a single measurement is noise.
- Array += rebuilds the array each iteration. Use a List.
- Filter at the source with -Filter rather than afterwards.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Times a loop with a stopwatch and returns the result and elapsed time together.
Show reference output
Illustrative output · values vary by environment
Sum Elapsed_ms --- ---------- 50005000 3