Profiler for PowerShell

repository·main·Indexed 41 days ago

https://github.com/nohwnd/profiler

A performance profiling tool for PowerShell 5 and 7 compatible with Windows, Linux, and MacOS. It enables developers to measure execution time for scripts, scriptblocks, and modules using commands like Trace-Script and Invoke-Script, providing detailed breakdowns of self-duration versus total duration and exporting results in speedscope.app format.

Tokens
724
Snippets
5
Records
6
Agent score
2%

What's inside Profiler

  1. Known limitations of Profiler

    main

    Be aware of the following constraints when using the Profiler:

    • PSDebug Interference: Using Set-PSDebug -Off or Set-PSDebug -Trace 0 will stop the tracing, as the module relies on these internally to enable/disable tracing.
    • Breakpoint Interference: Removing all breakpoints from the current session will stop tracing. While the module attempts to use a synthetic breakpoint to prevent this, code that explicitly removes all existing breakpoints may break the profiler.
  2. Profile module functions or complex scriptblocks

    main

    You can profile any arbitrary scriptblock, which allows you to include module imports and multiple commands within the profiled scope.

    $scriptBlock = { 
        Import-Module Pester
        Invoke-Pester
    }
    Trace-Script -ScriptBlock $scriptBlock
  3. Compare performance using Invoke-Script

    main

    To compare performance before and after changes, use Invoke-Script. This allows you to run the code multiple times and use a -Flag to identify specific runs (e.g., for a profiler toggle).

    Key parameters:

    • -Preheat: Number of times to run the code before starting the actual measurement.
    • -Repeat: Number of times to repeat the execution.
    • -Flag: An options hashtable used to pass flags to the script.
    $flag = @{ _profiler = $true }
    Invoke-Script -ScriptBlock $scriptBlock -Preheat 0 -Repeat 3 -Flag $flag
  4. Trace a script or scriptblock with Trace-Script

    main

    Use Trace-Script to profile the execution of a script or a scriptblock. You can provide a -ScriptBlock to run specific code and an -ExportPath to save the results in the speedscope.app format for graphical analysis.

    When inspecting results:

    • SelfPercent and SelfDuration: Time spent only in the function, excluding calls to other code.
    • Percent and Duration: Total time taken by the function including all code it calls.
    $trace = Trace-Script -ScriptBlock { & "demo-scripts/Get-Icons.ps1" } -ExportPath icons
    $trace.Top50SelfDuration
  5. Retrieve the last trace with Get-LatestTrace

    main

    If you run a profiling command but did not assign its output to a variable, you can retrieve the most recent trace using Get-LatestTrace.

    # If you ran a command without assignment:
    # Invoke-Script -ScriptBlock $scriptBlock ...
    
    $trace = Get-LatestTrace
    $trace.Top50Duration