|
| 1 | +--- |
| 2 | +name: startup-perf |
| 3 | +description: Measures Aspire application startup performance using dotnet-trace and the TraceAnalyzer tool. Use this when asked to measure impact of a code change on Aspire application startup performance. |
| 4 | +--- |
| 5 | + |
| 6 | +# Aspire Startup Performance Measurement |
| 7 | + |
| 8 | +This skill provides patterns and practices for measuring .NET Aspire application startup performance using the `Measure-StartupPerformance.ps1` script and the companion `TraceAnalyzer` tool. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +The startup performance tooling collects `dotnet-trace` traces from an Aspire AppHost application and computes the startup duration from `AspireEventSource` events. Specifically, it measures the time between the `DcpModelCreationStart` (event ID 17) and `DcpModelCreationStop` (event ID 18) events emitted by the `Microsoft-Aspire-Hosting` EventSource provider. |
| 13 | + |
| 14 | +**Script Location**: `tools/perf/Measure-StartupPerformance.ps1` |
| 15 | +**TraceAnalyzer Location**: `tools/perf/TraceAnalyzer/` |
| 16 | +**Documentation**: `docs/getting-perf-traces.md` |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +- PowerShell 7+ |
| 21 | +- `dotnet-trace` global tool (`dotnet tool install -g dotnet-trace`) |
| 22 | +- .NET SDK (restored via `./restore.cmd` or `./restore.sh`) |
| 23 | + |
| 24 | +## Quick Start |
| 25 | + |
| 26 | +### Single Measurement |
| 27 | + |
| 28 | +```powershell |
| 29 | +# From repository root — measures the default TestShop.AppHost |
| 30 | +.\tools\perf\Measure-StartupPerformance.ps1 |
| 31 | +``` |
| 32 | + |
| 33 | +### Multiple Iterations with Statistics |
| 34 | + |
| 35 | +```powershell |
| 36 | +.\tools\perf\Measure-StartupPerformance.ps1 -Iterations 5 |
| 37 | +``` |
| 38 | + |
| 39 | +### Custom Project |
| 40 | + |
| 41 | +```powershell |
| 42 | +.\tools\perf\Measure-StartupPerformance.ps1 -ProjectPath "path\to\MyApp.AppHost.csproj" -Iterations 3 |
| 43 | +``` |
| 44 | + |
| 45 | +### Preserve Traces for Manual Analysis |
| 46 | + |
| 47 | +```powershell |
| 48 | +.\tools\perf\Measure-StartupPerformance.ps1 -Iterations 3 -PreserveTraces -TraceOutputDirectory "C:\traces" |
| 49 | +``` |
| 50 | + |
| 51 | +### Verbose Output |
| 52 | + |
| 53 | +```powershell |
| 54 | +.\tools\perf\Measure-StartupPerformance.ps1 -Verbose |
| 55 | +``` |
| 56 | + |
| 57 | +## Parameters |
| 58 | + |
| 59 | +| Parameter | Default | Description | |
| 60 | +|-----------|---------|-------------| |
| 61 | +| `ProjectPath` | TestShop.AppHost | Path to the AppHost `.csproj` to measure | |
| 62 | +| `Iterations` | 1 | Number of measurement runs (1–100) | |
| 63 | +| `PreserveTraces` | `$false` | Keep `.nettrace` files after analysis | |
| 64 | +| `TraceOutputDirectory` | temp folder | Directory for preserved trace files | |
| 65 | +| `SkipBuild` | `$false` | Skip `dotnet build` before running | |
| 66 | +| `TraceDurationSeconds` | 60 | Maximum trace collection time (1–86400) | |
| 67 | +| `PauseBetweenIterationsSeconds` | 45 | Pause between iterations (0–3600) | |
| 68 | +| `Verbose` | `$false` | Show detailed output | |
| 69 | + |
| 70 | +## How It Works |
| 71 | + |
| 72 | +The script follows this sequence: |
| 73 | + |
| 74 | +1. **Prerequisites check** — Verifies `dotnet-trace` is installed and the project exists. |
| 75 | +2. **Build** — Builds the AppHost project in Release configuration (unless `-SkipBuild`). |
| 76 | +3. **Build TraceAnalyzer** — Builds the companion `tools/perf/TraceAnalyzer` project. |
| 77 | +4. **For each iteration:** |
| 78 | + a. Locates the compiled executable (Arcade-style or traditional output paths). |
| 79 | + b. Reads `launchSettings.json` for environment variables. |
| 80 | + c. Launches the AppHost as a separate process. |
| 81 | + d. Attaches `dotnet-trace` to the running process with the `Microsoft-Aspire-Hosting` provider. |
| 82 | + e. Waits for the trace to complete (duration timeout or process exit). |
| 83 | + f. Runs the TraceAnalyzer to extract the startup duration from the `.nettrace` file. |
| 84 | + g. Cleans up processes. |
| 85 | +5. **Reports results** — Prints per-iteration times and statistics (min, max, average, std dev). |
| 86 | + |
| 87 | +## TraceAnalyzer Tool |
| 88 | + |
| 89 | +The `tools/perf/TraceAnalyzer` is a small .NET console app that parses `.nettrace` files using the `Microsoft.Diagnostics.Tracing.TraceEvent` library. |
| 90 | + |
| 91 | +### What It Does |
| 92 | + |
| 93 | +- Opens the `.nettrace` file with `EventPipeEventSource` |
| 94 | +- Listens for events from the `Microsoft-Aspire-Hosting` provider |
| 95 | +- Extracts timestamps for `DcpModelCreationStart` (ID 17) and `DcpModelCreationStop` (ID 18) |
| 96 | +- Outputs the duration in milliseconds (or `"null"` if events are not found) |
| 97 | + |
| 98 | +### Standalone Usage |
| 99 | + |
| 100 | +```bash |
| 101 | +dotnet run --project tools/perf/TraceAnalyzer -c Release -- <path-to-nettrace-file> |
| 102 | +``` |
| 103 | + |
| 104 | +## Understanding Output |
| 105 | + |
| 106 | +### Successful Run |
| 107 | + |
| 108 | +``` |
| 109 | +================================================== |
| 110 | + Aspire Startup Performance Measurement |
| 111 | +================================================== |
| 112 | +
|
| 113 | +Project: TestShop.AppHost |
| 114 | +Iterations: 3 |
| 115 | +... |
| 116 | +
|
| 117 | +Iteration 1 |
| 118 | +---------------------------------------- |
| 119 | +Starting TestShop.AppHost... |
| 120 | +Attaching trace collection to PID 12345... |
| 121 | +Collecting performance trace... |
| 122 | +Trace collection completed. |
| 123 | +Analyzing trace: ... |
| 124 | +Startup time: 1234.56 ms |
| 125 | +
|
| 126 | +... |
| 127 | +
|
| 128 | +================================================== |
| 129 | + Results Summary |
| 130 | +================================================== |
| 131 | +
|
| 132 | +Iteration StartupTimeMs |
| 133 | +--------- ------------- |
| 134 | + 1 1234.56 |
| 135 | + 2 1189.23 |
| 136 | + 3 1201.45 |
| 137 | +
|
| 138 | +Statistics: |
| 139 | + Successful iterations: 3 / 3 |
| 140 | + Minimum: 1189.23 ms |
| 141 | + Maximum: 1234.56 ms |
| 142 | + Average: 1208.41 ms |
| 143 | + Std Dev: 18.92 ms |
| 144 | +``` |
| 145 | + |
| 146 | +### Common Issues |
| 147 | + |
| 148 | +| Symptom | Cause | Fix | |
| 149 | +|---------|-------|-----| |
| 150 | +| `dotnet-trace is not installed` | Missing global tool | Run `dotnet tool install -g dotnet-trace` | |
| 151 | +| `Could not find compiled executable` | Project not built | Remove `-SkipBuild` or build manually | |
| 152 | +| `Could not find DcpModelCreation events` | Trace too short or events not emitted | Increase `-TraceDurationSeconds` | |
| 153 | +| `Application exited immediately` | App crash on startup | Check app logs, ensure dependencies are available | |
| 154 | +| `dotnet-trace exited with code != 0` | Trace collection error | Check verbose output; trace file may still be valid | |
| 155 | + |
| 156 | +## Comparing Before/After Performance |
| 157 | + |
| 158 | +To measure the impact of a code change: |
| 159 | + |
| 160 | +```powershell |
| 161 | +# 1. Measure baseline (on main branch) |
| 162 | +git checkout main |
| 163 | +.\tools\perf\Measure-StartupPerformance.ps1 -Iterations 5 -PreserveTraces -TraceOutputDirectory "C:\traces\baseline" |
| 164 | +
|
| 165 | +# 2. Measure with changes |
| 166 | +git checkout my-feature-branch |
| 167 | +.\tools\perf\Measure-StartupPerformance.ps1 -Iterations 5 -PreserveTraces -TraceOutputDirectory "C:\traces\feature" |
| 168 | +
|
| 169 | +# 3. Compare the reported averages and std devs |
| 170 | +``` |
| 171 | + |
| 172 | +Use enough iterations (5+) and a consistent pause between iterations for reliable comparisons. |
| 173 | + |
| 174 | +## Collecting Traces for Manual Analysis |
| 175 | + |
| 176 | +If you need to inspect trace files manually (e.g., in PerfView or Visual Studio): |
| 177 | + |
| 178 | +```powershell |
| 179 | +.\tools\perf\Measure-StartupPerformance.ps1 -PreserveTraces -TraceOutputDirectory "C:\my-traces" |
| 180 | +``` |
| 181 | + |
| 182 | +See `docs/getting-perf-traces.md` for guidance on analyzing traces with PerfView or `dotnet trace report`. |
| 183 | + |
| 184 | +## EventSource Provider Details |
| 185 | + |
| 186 | +The `Microsoft-Aspire-Hosting` EventSource emits events for key Aspire lifecycle milestones. The startup performance script focuses on: |
| 187 | + |
| 188 | +| Event ID | Event Name | Description | |
| 189 | +|----------|------------|-------------| |
| 190 | +| 17 | `DcpModelCreationStart` | Marks the beginning of DCP model creation | |
| 191 | +| 18 | `DcpModelCreationStop` | Marks the completion of DCP model creation | |
| 192 | + |
| 193 | +The measured startup time is the wall-clock difference between these two events, representing the time to create all application services and supporting dependencies. |
0 commit comments