[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-github-build-performance-analysis":3,"mdc--hovmjg-key":33,"related-org-github-build-performance-analysis":4827,"related-repo-github-build-performance-analysis":5004},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":28,"sourceUrl":31,"mdContent":32},"build-performance-analysis","analyze C++ build performance","Analyze C++ build performance using vcperf.exe and ETL traces. Use this skill when the user wants to profile a build, understand compile bottlenecks, identify expensive headers or templates, generate JSON analysis reports, or interpret vcperf output. Covers tracing workflows, the \u002FjsonAnalysis flag, reading the resulting JSON schema, and actionable remediation strategies for each bottleneck category.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"github","GitHub","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fgithub.png",[12,16,19],{"name":13,"slug":14,"type":15},"Performance","performance","tag",{"name":17,"slug":18,"type":15},"Engineering","engineering",{"name":20,"slug":21,"type":15},"Debugging","debugging",321,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fcopilot-plugins","2026-08-03T06:27:17.684587",null,83,[],{"repoUrl":23,"stars":22,"forks":26,"topics":29,"description":30},[],"The official GitHub Copilot plugins collection — MCP servers, skills, hooks, and other extensibility tools for GitHub Copilot.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fcopilot-plugins\u002Ftree\u002FHEAD\u002Fplugins\u002Fbuild-perf-cpp\u002Fskills\u002Fbuild-performance-analysis","---\r\nname: build-performance-analysis\r\ndescription: >\r\n  Analyze C++ build performance using vcperf.exe and ETL traces. Use this skill\r\n  when the user wants to profile a build, understand compile bottlenecks, identify\r\n  expensive headers or templates, generate JSON analysis reports, or interpret\r\n  vcperf output. Covers tracing workflows, the \u002FjsonAnalysis flag, reading\r\n  the resulting JSON schema, and actionable remediation strategies for each\r\n  bottleneck category.\r\ncompatibility: Windows with MSVC toolchain. Requires administrator privileges for default tracing.\r\n---\r\n\r\n# Build Performance Analysis with vcperf.exe\r\n\r\n## Execution order\r\n\r\nA single **workflow**, always run in order.\r\n\r\n### Workflow — always run, in order\r\n\r\n**Treat each session as independent.** Re-capture traces, JSON analysis, and baseline measurements fresh each session instead of reusing data from a previous session — the one-time trace-permission grant persists.\r\n\r\n1. [Prerequisites: Trace Permission](#prerequisites-trace-permission) — grant ETW rights. Run **before** any workspace exploration (project enumeration, file listing, code search).\r\n2. [Core Workflow](#core-workflow) + [The \u002FjsonAnalysis Flag](#the-jsonanalysis-flag)\r\n3. [Baseline Measurement](#baseline-measurement) — 5 uninstrumented clean rebuilds of the **pre-change** state; average for a stable baseline. **Make no code or project edits during this step**.\r\n4. [Remediation Strategies](#remediation-strategies) — the **first** step where you edit anything; apply changes informed by Steps 2–3.\r\n5. [Measuring Final Performance Improvement](#measuring-final-performance-improvement) — 5 uninstrumented clean rebuilds of the post-change state; compare against the baseline. If a PCH or template change shows a neutral or regressed delta, also run [Iterative Build Measurement](#iterative-build-measurement).\r\n\r\n## Which vcperf.exe executable should I use?\r\n\r\nThe `sessionStart` hook installs `vcperf.exe` under `%LOCALAPPDATA%\\vcperf\\build-perf-cpp` (multiple versions may coexist). Resolve the **newest** version once and reuse it:\r\n\r\n```powershell\r\n$vcperfPkg = Get-ChildItem \"$env:LOCALAPPDATA\\vcperf\\build-perf-cpp\" -Directory -Filter 'Microsoft.Cpp.vcperf.*' -ErrorAction SilentlyContinue | Sort-Object { ($_.Name -replace '^Microsoft\\.Cpp\\.vcperf\\.', '' -split '\\.' | ForEach-Object { ([long]$_).ToString().PadLeft(20, '0') }) -join '.' } -Descending | Select-Object -First 1\r\n$vcperf = if ($vcperfPkg) { (Get-ChildItem $vcperfPkg.FullName -Recurse -Filter vcperf.exe | Where-Object DirectoryName -like '*\\x64' | Select-Object -First 1).FullName }\r\n```\r\n\r\n**Authentication**: If `$vcperf` resolves empty, read `references\u002Ffeed-auth.md` and follow it before proceeding.\r\n\r\n### Invocation rule (read before running any vcperf command)\r\n\r\nEvery `vcperf` command below runs the resolved `$vcperf` path directly in PowerShell (`& $vcperf ...`). Both rules are mandatory:\r\n\r\n1. **Use the absolute `$vcperf` path, never a bare `vcperf`.** Bare `vcperf` resolves off `PATH` to the older Visual-Studio-bundled copy (may lack `\u002FjsonAnalysis`), not the one under `%LOCALAPPDATA%\\vcperf\\build-perf-cpp`.\r\n2. **Judge success by the output file, not `$LASTEXITCODE`.** PowerShell's `& $vcperf` can surface an internal COM `HRESULT` (e.g. `0x80040013`) in `$LASTEXITCODE` and render output as blank lines, so a run that actually succeeded can look failed. After a `\u002Fstop` or `\u002Fstopnoanalyze`, confirm the expected `.etl`\u002F`.json` file was written (`Test-Path`) instead of trusting the exit code.\r\n\r\nThe command blocks in [Prerequisites](#prerequisites-trace-permission) and [Core Workflow](#core-workflow) below apply both rules — follow their exact form.\r\n\r\n## What is vcperf?\r\n\r\nvcperf.exe captures and analyzes C++ build traces using the C++ Build Insights SDK. It records ETW events during MSVC compilations and produces either ETL files (for Windows Performance Analyzer) or structured JSON reports.\r\n\r\n## Prerequisites: Trace Permission\r\n\r\n`vcperf \u002Fstart` writes ETW providers that require **either**:\r\n\r\n- the invoking process to be **elevated (Administrator)**, OR\r\n- a one-time **`vcperf \u002Fgrantusercontrol`** run elevated for the current user — after which non-admin invocations may use `\u002Fstart \u002Fnoadmin` (reduced data: no CPU sampling).\r\n\r\nThe CLI agent runs unelevated and **must solve this itself** — do not ask the user to \"open an elevated prompt and run X by hand\".\r\n\r\nRun on first use. Once Step 4 verifies the grant, Step 4b persists a per-user marker file so **future sessions skip Trace Permission Steps 2–4 entirely**. Within a session, also cache the Step 1 result in working memory. **Skip entirely for `vcperf \u002Fanalyze` and `vcperf \u002Fstop` against an existing trace** — only `\u002Fstart` needs the grant.\r\n\r\n\r\n### Step 1 — Check whether rights already exist\r\n\r\nTwo signals; either is sufficient. **Run Check A first; skip Check B if A is true.**\r\n\r\n**Check A — process is elevated:**\r\n\r\n```powershell\r\n$isAdmin = ([Security.Principal.WindowsPrincipal]::new(\r\n    [Security.Principal.WindowsIdentity]::GetCurrent())\r\n).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)\r\n```\r\n\r\nIf `$isAdmin` is `$true` → skip to Step 5.\r\n\r\n**Check B — agent-persisted grant marker** (only when Check A is false):\r\n\r\n```powershell\r\n$grantMarker = Join-Path $env:LOCALAPPDATA 'vcperf\\grant-verified'\r\n$hasGrantMarker = Test-Path -LiteralPath $grantMarker -PathType Leaf\r\n\r\n```\r\n\r\nIf `$hasGrantMarker` is `$true`, the agent already granted and verified rights in a previous session — proceed without re-prompting.\r\n\r\n**If Check A OR Check B is true → you have rights. Skip to Step 5.**\r\n\r\n### Step 2 — Ask the user before triggering UAC (REQUIRED)\r\n\r\nIf neither check is true, you MUST get explicit consent before launching an elevated process. **Use the `ask_user` tool — never just print prompt text in chat.**\r\n\r\n```\r\nask_user(\r\n  question = \"vcperf needs additional permissions to execute a trace. May I run a one-time elevated `vcperf \u002Fgrantusercontrol`? A UAC prompt will appear.\",\r\n  choices  = [\"Yes (Recommended)\", \"No\"]\r\n)\r\n```\r\n\r\nIf the user answers **No**, stop the workflow. Report that vcperf cannot run without trace permission and let the user decide how to proceed. Do NOT fall through to Step 3, do not retry, and do not silently downgrade to a non-vcperf measurement.\r\n\r\n### Step 3 — Grant rights elevated\r\n\r\nLaunch an elevated PowerShell that runs `vcperf \u002Fgrantusercontrol` and wait for it. The grant produces no output artifact, so Step 4 verifies it functionally:\r\n\r\n```powershell\r\n# $vcperf must already hold the absolute path (see resolution block above).\r\n# \u002Fgrantusercontrol writes no output file, so Step 4 verifies it functionally;\r\n# we don't depend on vcperf's exit code here (see Invocation rule).\r\ntry {\r\n    Start-Process powershell.exe `\r\n        -ArgumentList '-NoProfile','-Command',\"& '$vcperf' \u002Fgrantusercontrol\" `\r\n        -Verb RunAs -Wait\r\n    $grantCancelled = $false\r\n} catch [System.ComponentModel.Win32Exception] {\r\n    if ($_.Exception.NativeErrorCode -eq 1223) {\r\n        # Win32 error 1223 = ERROR_CANCELLED — user dismissed the UAC prompt.\r\n        $grantCancelled = $true\r\n    } else {\r\n        throw\r\n    }\r\n}\r\n$grantCancelled\r\n```\r\n\r\n- A UAC dialog will appear. If the user cancels it, `Start-Process -Verb RunAs` throws `Win32Exception` with `NativeErrorCode = 1223` — treat that as \"user declined\" and stop (same outcome as a \"No\" in Step 2).\r\n- Otherwise the elevated grant ran. Its exit code is not reliable (see Invocation rule), so **Step 4 is the authoritative check** that the grant actually worked — proceed there.\r\n\r\n### Step 4 — Verify the grant worked\r\n\r\nDo not trust Step 3 alone — run a functional probe. Use `\u002Fstopnoanalyze` (not `\u002Fstop`); the probe only needs to prove `\u002Fstart \u002Fnoadmin` succeeded, and `\u002Fstop` would waste seconds analyzing an empty session.\r\n\r\n```powershell\r\n$probe   = 'PermProbe_' + [guid]::NewGuid().ToString('N').Substring(0,8)\r\n$probeEtl = Join-Path $env:TEMP \"$probe.etl\"\r\nRemove-Item $probeEtl -ErrorAction SilentlyContinue\r\n# Success signal is whether the probe ETL is produced, not $LASTEXITCODE\r\n# (see Invocation rule). A working \u002Fstart + \u002Fstopnoanalyze writes the ETL;\r\n# if \u002Fstart was denied, no ETL appears.\r\n$startOutput = (& $vcperf \u002Fstart \u002Fnoadmin $probe *>&1 | Out-String).Trim()\r\n$stopOutput = (& $vcperf \u002Fstopnoanalyze $probe $probeEtl *>&1 | Out-String).Trim()\r\n$started = Test-Path $probeEtl\r\nif (-not $started) {\r\n    $probeOutput = @($startOutput, $stopOutput) | Where-Object { $_ }\r\n    Write-Error (\"vcperf permission probe failed.`n\" + ($probeOutput -join \"`n\"))\r\n}\r\nRemove-Item $probeEtl -ErrorAction SilentlyContinue\r\n$started\r\n```\r\n\r\nIf `$started` is `$true`, the grant is verified — proceed. If `$false`, the grant did not take effect — surface the failure with the vcperf output and stop. Do not silently retry. **Do NOT run Step 4b on a failed verify.**\r\n\r\n### Step 4b — Persist the verified grant (so future sessions skip Steps 2–4)\r\n\r\nRun only **after** Step 4 returned `$started = $true`. Write the per-user **marker file** that Check B reads:\r\n\r\n```powershell\r\n$grantMarker = Join-Path $env:LOCALAPPDATA 'vcperf\\grant-verified'\r\nNew-Item -Path (Split-Path $grantMarker -Parent) -ItemType Directory -Force | Out-Null\r\n$payload = @{ grantedUtc = (Get-Date).ToUniversalTime().ToString('o'); vcperf = $vcperf } | ConvertTo-Json -Compress\r\n[IO.File]::WriteAllText(\"$grantMarker.tmp\", $payload, [Text.Encoding]::UTF8)\r\n\r\nMove-Item -LiteralPath \"$grantMarker.tmp\" -Destination $grantMarker -Force\r\n```\r\n\r\n- Check presence of marker file to determine if grant is persisted.\r\n- On every subsequent session, Check B returns `$true` and the agent skips straight to Step 5.\r\n\r\n### Step 5 — Invoke vcperf with the right flag\r\n\r\nWhen starting the tracing session:\r\n\r\n- **always** pass `\u002Fnoadmin` to `vcperf \u002Fstart`, or the start will fail with a privilege error.\r\n- **Stale-grant recovery.** If `\u002Fstart \u002Fnoadmin` fails with a privilege error while Check B was `$true`, the cached grant is stale (the underlying ETW grant was revoked outside the agent). Recover by running Steps 2–4 directly — **skip Step 1**.\r\n\r\n\r\n## Core Workflow\r\n\r\nThere are three phases: **start** a trace, **build** your project, then **stop** and **analyze** to produce results.\r\n\r\n> Below, `vcperf` is shorthand for the resolved `$vcperf` absolute path run directly in PowerShell (`& $vcperf ...`), per the [Invocation rule](#invocation-rule-read-before-running-any-vcperf-command). Never run a bare `vcperf` (it hits the VS-bundled copy on `PATH`), and judge success by the output file rather than `$LASTEXITCODE`.\r\n\r\n### 1. Start a tracing session\r\n\r\n```\r\nvcperf \u002Fstart [\u002Fnoadmin] [\u002Fnocpusampling] [\u002Flevel1 | \u002Flevel2 | \u002Flevel3] \u003CsessionName>\r\n```\r\n\r\n| Flag | Purpose |\r\n|------|---------|\r\n| `\u002Fnoadmin` | Run without admin (less data) |\r\n| `\u002Fnocpusampling` | Skip CPU sampling |\r\n| `\u002Flevel1` | Basic events |\r\n| `\u002Flevel2` | Adds additional detail |\r\n| `\u002Flevel3` | Maximum detail, includes template instantiation data |\r\n\r\nUse `\u002Flevel3` when you plan to analyze templates.\r\n\r\n### 2. Build your project\r\n\r\nRun your normal build command while the trace is active. Any MSVC-driven build works — MSBuild, CMake (Ninja or MSBuild generator), or direct `cl.exe`. The *compiler* must be MSVC; the *build driver* is your choice.\r\n\r\nWhen building solution files, look for either `.sln` or `.slnx`.\r\n\r\n#### Build configuration matters (Debug vs Release)\r\n\r\nvcperf only reports work the compiler actually performs. **Debug** builds skip most optimizer passes, so the `Functions` section of the JSON output will be sparse or empty — you will not see backend codegen, inlining, or optimization hotspots. Frontend phases (`IncludedFiles`, `Templates`) are still captured normally because parsing and template instantiation happen regardless of configuration.\r\n\r\nFor meaningful function-level analysis, build in **Release** (or another optimized configuration such as `RelWithDebInfo`). As a rule, profile the configuration you intend to ship; before choosing Debug, confirm with the user that frontend-only data is enough for their question, and call out the missing `Functions` data in your report.\r\n\r\n### 3. Stop and analyze\r\n\r\n```\r\nvcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> output.etl\r\nvcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> output.etl \u002FjsonAnalysis output.json\r\nvcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> \u002Ftimetrace output.json\r\n```\r\n\r\nOr capture raw first, then analyze offline:\r\n\r\n```\r\nvcperf \u002Fstopnoanalyze \u003CsessionName> raw.etl\r\nvcperf \u002Fanalyze [\u002Ftemplates] raw.etl output.etl \u002FjsonAnalysis output.json\r\n```\r\n\r\n### 4. Avoid timing gaps — run start\u002Fbuild\u002Fstop as one shell command\r\n\r\n`vcperf` records ETW events from `\u002Fstart` until `\u002Fstop`. **Any wall-clock gap between `\u002Fstart`, the build, and `\u002Fstop` is captured as noise** — model thinking, tool-call round-trips, prompts, and shell startup all inflate `BuildDurationMs` and can shift hotspot rankings.\r\n\r\nFrom a CLI agent or any interactive workflow, **chain `\u002Fstart → build → \u002Fstop` into a single shell command**. Do not issue them as three separate tool calls — the latency between calls (often several seconds each) contaminates the trace.\r\n\r\n**PowerShell with MSBuild (single invocation — recommended):**\r\n```powershell\r\n# $vcperf holds the absolute path resolved earlier. Run as one scriptblock so\r\n# \u002Fstart -> build -> \u002Fstop execute back-to-back with no timing gaps. Judge trace\r\n# success by the output files (Test-Path), not $LASTEXITCODE (see Invocation rule).\r\n\r\n$buildExit = & {\r\n    & $vcperf \u002Fstart \u002Fnoadmin \u002Flevel3 MySession | Out-Host\r\n    msbuild Project.sln \u002Fm \u002Ft:Rebuild \u002Fp:Configuration=Release | Out-Host\r\n    $exitCode = $LASTEXITCODE\r\n    & $vcperf \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json | Out-Host\r\n    $exitCode\r\n}\r\n$traceOk = (Test-Path out.etl) -and (Test-Path out.json)\r\n```\r\n\r\n**PowerShell with CMake (single invocation):**\r\n```powershell\r\n$buildExit = & {\r\n    & $vcperf \u002Fstart \u002Fnoadmin \u002Flevel3 MySession | Out-Host\r\n    cmake --build build --target clean | Out-Host\r\n    cmake --build build --parallel | Out-Host\r\n    $exitCode = $LASTEXITCODE\r\n    & $vcperf \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json | Out-Host\r\n    $exitCode\r\n}\r\n$traceOk = (Test-Path out.etl) -and (Test-Path out.json)\r\n```\r\n`$buildExit` is the build tool's own exit code (reliable — an ordinary process), telling you whether the build succeeded. `$traceOk` confirms vcperf actually produced the trace. The `;` sequence never short-circuits, so `\u002Fstop` always runs even if the build fails.\r\n\r\n**cmd.exe alternative** (if you prefer `&&` short-circuit semantics; substitute the full path for `%VCPERF%`):\r\n```cmd\r\n\"%VCPERF%\" \u002Fstart \u002Fnoadmin \u002Flevel3 MySession && cmake --build build --target clean && cmake --build build --parallel && \"%VCPERF%\" \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json\r\n```\r\n`&&` skips `\u002Fstop` if the build fails; replace the `&&` before the final `\"%VCPERF%\" \u002Fstop` with `&` to emit the trace anyway.\r\n\r\nThe same rule applies to incremental measurements (see [Iterative Build Measurement](#iterative-build-measurement)): the touch step may be a separate command, but `\u002Fstart → build → \u002Fstop` must be one chained invocation.\r\n\r\n## The \u002FjsonAnalysis Flag\r\n\r\nProduces a structured JSON report alongside the ETL output.\r\n\r\n**Syntax:** `\u002FjsonAnalysis \u003Cpath>.json` — must appear **after** the ETL output path.\r\n\r\n**Constraints:**\r\n- Cannot be combined with `\u002Ftimetrace` (mutually exclusive).\r\n- Pair with `\u002Ftemplates` to include template data.\r\n\r\n**Example:**\r\n```\r\nvcperf \u002Fstop \u002Ftemplates MyBuild output.etl \u002FjsonAnalysis analysis.json\r\n```\r\n\r\n## JSON Output Schema\r\n\r\nSee [references\u002Fjson-schema.md](references\u002Fjson-schema.md) for the full field-by-field schema of the JSON analysis output, including `IncludedFiles`, `Functions`, `Templates`, and `IncludeTree` sections.\r\n\r\n---\r\n\r\n## Baseline Measurement\r\n\r\nEstablish a baseline **before** applying the candidate change. A single build measurement is noisy — file system caches, antivirus, background processes, and thermal throttling all introduce variance, so always run a 5-build sample.\r\n\r\n**Do not run vcperf during these builds.** The diagnostic trace that tells you *what* to change is captured separately via the [Core Workflow](#core-workflow); baseline and post-change timing builds are plain, uninstrumented wall-clock builds. vcperf's ETW instrumentation adds overhead that would contaminate timing comparisons.\r\n\r\n**Make no changes to the project while measuring the baseline.** No modifications to the project until all baseline builds complete.\r\n\r\n### Procedure\r\n\r\n1. **Run 5 builds** of the target as a full clean rebuild (clean before every build), **without vcperf**. Every run uses identical configuration, platform, build parallelism (e.g. MSBuild `\u002Fm`, CMake `--parallel`, ninja's default `-j`), and machine state (plugged in, no background load).\r\n2. **Average the 5 builds** for a stable baseline.\r\n3. Record the baseline average and standard deviation. Compare post-change measurements against this baseline using the same methodology (5 uninstrumented builds).\r\n4. **Measure wall-clock time** of each build (e.g. `Measure-Command { msbuild ... }` or `Measure-Command { cmake --build build }`, or the build driver's own elapsed time). Record in **seconds** — all measurements, deltas, and statistics in this skill are in seconds, never milliseconds. Do **not** use `BuildDurationMs` from a vcperf JSON; that field comes from an instrumented trace and is not the metric you are optimizing.\r\n5. **Keep fixed between runs:** build parallelism, build-server \u002F node reuse, configuration, platform, power state, source\u002Foutput state. Do not change any source files or project settings during baseline measurement.\r\n\r\n## Iterative Build Measurement\r\nUse this only **after one full rebuild**.\r\n\r\n### Procedure overview\r\n\r\nAn **A\u002FB comparison of two incremental builds** with an identical workload:\r\n\r\n- **A:** candidate changes applied, the same set of TUs forced dirty\r\n- **B:** candidate changes reverted, the same set of TUs forced dirty\r\n\r\nBoth runs must mark the same files dirty and start from a `.obj` state matching the source they are about to compile.\r\n\r\n### Step 1 — Pick the TU files to touch\r\n\r\nCombine two signals and **prefer their intersection** (fall back to whichever is non-empty):\r\n\r\nReuse the `\u002FjsonAnalysis` output from [Core Workflow](#core-workflow). After applying [the selection rules](#remediation-strategies), take the top expensive headers in `IncludedFiles`\r\n- **Frequently-changed TUs from git churn.** Use only commits **before the branch fork-point** (see \"Git History Rules\" below):\r\n  ```powershell\r\n  $forkPoint = git merge-base HEAD origin\u002Fmain\r\n  git log --name-only --pretty=format: $forkPoint -- '*.cpp' '*.cxx' '*.cc' '*.c' |\r\n      Where-Object { $_ } |\r\n      Group-Object | Sort-Object Count -Descending |\r\n      Select-Object -First 50\r\n  ```\r\n\r\n### Step 2 — Touch (do not edit) the chosen files\r\n\r\nUpdate last-write-time only:\r\n\r\n```powershell\r\n$touchTime = (Get-Date).ToUniversalTime()\r\nforeach ($file in $tuFiles) {\r\n    if (Test-Path $file) { (Get-Item $file).LastWriteTimeUtc = $touchTime }\r\n}\r\n```\r\n\r\n### Step 3 — Pair-and-alternate, 5 iterations each side\r\n\r\nMeasured builds are **plain, uninstrumented, non-vcperf** wall-clock builds (`Measure-Command { msbuild ... }` \u002F `Measure-Command { cmake --build build }`), recorded in **seconds**.\r\n\r\nFor each iteration:\r\n\r\n1. Ensure candidate changes are **applied** (`git stash pop` or be on the change branch); run a regular build to settle `.obj` state; touch the chosen TUs; run an uninstrumented incremental build. Record as **A** (with changes).\r\n2. **Revert** candidate changes (`git stash` or switch to base branch); run a regular build to settle `.obj` state; touch the same TUs; run an uninstrumented incremental build. Record as **B** (baseline).\r\n\r\nThe \"settle `.obj` state\" build after each switch is mandatory — skip it and A and B compile different amounts of code. **Alternate** A and B per iteration (not 5 As then 5 Bs) to average out warm-cache and thermal effects.\r\n\r\n### Step 4 — Compare and report\r\n\r\nMeaningful improvement is `A_avg \u003C B_avg - B_stddev` (same rule as the rebuild baseline). Report all times in **seconds** with the standard deviation in its own column (no `mean ± stddev` shorthand):\r\n\r\n| Variant | Mean (s) | StdDev (s) |\r\n|---|---|---|\r\n| A (with changes) | ... | ... |\r\n| B (baseline) | ... | ... |\r\n\r\nAlso report the number of TUs touched, `delta_s = B_avg - A_avg` (positive = improvement), and `delta_pct = delta_s \u002F B_avg * 100`.\r\n\r\n## Git History Rules\r\n\r\n**CRITICAL:** Do not use git history (log, blame, diff) for commits **after** the branch fork-point (merge-base with the base branch). Build performance analysis evaluates the current state of the code — post-fork-point history can bias optimization decisions.\r\n\r\nYou MAY use git history for commits **before** the fork-point to understand:\r\n- When a header was introduced or significantly changed.\r\n- Historical context for why a particular include structure exists.\r\n- Whether a PCH previously existed and was removed.\r\n\r\n## Remediation Strategies\r\n\r\nAfter producing a JSON analysis report and **applying the selection rules above**, use the strategies below to fix each category. Always **re-profile after each change** to verify improvement and catch regressions.\r\n\r\n### Expensive Included Files (`IncludedFiles`)\r\n\r\nHeaders with high WCTR and high include counts are the highest-leverage targets. A header included in N translation units has its parse cost multiplied N times.\r\n\r\n#### Strategy 1 — Use or create a precompiled header (PCH)\r\nA PCH parses expensive headers once and reuses the result across all translation\r\nunits. This is the single most effective technique for headers that are both\r\nexpensive and widely included.\r\n\r\n**When to use:**\r\n- Headers with high WCTR, high include count, and low change frequency.\r\n- STL headers (`\u003Cstring>`, `\u003Cvector>`, `\u003Cmap>`, `\u003Cmemory>`, etc.) are ideal\r\n  because they never change.\r\n- Third-party library headers (GLM, SDL, fmt, etc.) are excellent candidates.\r\n- Stable project headers that are included in many TUs but rarely modified.\r\n\r\n**How to evaluate project headers for PCH inclusion:**\r\n1. Check the header's WCTR and include count from the JSON report.\r\n2. Check change frequency: `git log --oneline --since=\"1 year ago\" -- path\u002Fto\u002Fheader.hpp`\r\n\r\n**PCH header selection tiers:**\r\n| Tier | Type | Example | Risk |\r\n|------|------|---------|------|\r\n| 1 (always safe) | STL headers | `\u003Cstring>`, `\u003Cvector>` | None — never change |\r\n| 2 (safe) | Third-party | `\u003Cglm\u002Fglm.hpp>`, `\u003CSDL.h>` | Low — change only on dependency upgrade |\r\n| 3 (evaluate) | Stable project | Core type headers, rendering API | Medium — check git history first |\r\n| 4 (avoid) | Volatile project | Actively developed feature headers | High — triggers frequent full rebuilds |\r\n\r\nIf the PCH change already shows a statistically significant clean-rebuild improvement, **the change is validated — do not run the iterative workflow.**\r\n\r\n#### Strategy 2 — Use forward declarations\r\n\r\nIf a header only uses pointers or references to a type, it does not need the full definition — a forward declaration suffices.\r\n\r\n1. In headers, replace `#include \"foo.hpp\"` with `class Foo;` when only `Foo*`, `Foo&`, or `std::unique_ptr\u003CFoo>` are used.\r\n2. Move `#include \"foo.hpp\"` to the `.cpp` file where the full definition is needed.\r\n3. Consider a project `fwd.hpp` that collects common forward declarations for widely-used types.\r\n\r\n#### Strategy 3 — Flatten include chains\r\n\r\nDeeply nested include chains amplify costs. If header A includes B which includes C which includes D, every file that includes A pays for all four.\r\n\r\n1. Use `IncludeTree` to identify deep chains.\r\n2. Audit intermediate headers — do they really need everything they include?\r\n3. Break long chains by removing unnecessary intermediate includes; have consumers include what they need directly.\r\n\r\n---\r\n\r\n### Expensive Functions (`Functions`)\r\n\r\nFunctions with high WCTR are expensive during the back-end code generation (compilation\u002Flinking) phase.\r\n\r\n#### Strategy 1 — Reduce `__forceinline` and excessive inlining\r\n\r\nThe `forceinlineSize` field reveals how much code is inlined into each function. The larger this value relative to other entries in the post-filter top-15, the more aggressive inlining has bloated the function's body.\r\n\r\n1. Compare `forceinlineSize` across the top-15 entries — the entries at the top of the weighted ranking are the ones whose inline bloat is paying off the least.\r\n2. Find functions or methods marked `__forceinline`, `__attribute__((always_inline))`, or defined in headers as `inline` that are called from the expensive function. **Use the demangled `functionName`** — the raw JSON name is decorated and will not match source-text grep.\r\n3. Move large inline function bodies from headers to `.cpp` files (see Strategy 3 below).\r\n4. Replace `__forceinline` with regular `inline` or no annotation — let the compiler decide. Reserve `__forceinline` for genuinely tiny, hot-path functions.\r\n5. For template-heavy code, consider explicit template instantiation in a `.cpp` file to avoid redundant codegen across TUs.\r\n\r\n#### Strategy 2 — Break up large functions\r\n\r\nVery large functions are expensive to optimize (register allocation, instruction scheduling, etc.).\r\n\r\n1. Identify functions among the post-filter top-15 whose `wallClockMillisecondTimeResponsibility` is large relative to others in the list. The relative ranking is the signal — there is no absolute time cutoff.\r\n2. Extract logically independent sections into separate helper functions.\r\n3. Move cold paths (error handling, logging, rare branches) into separate `__declspec(noinline)` or `[[gnu::noinline]]` functions to reduce optimizer workload on the hot path.\r\n4. **Prefer breaking up before marking `noinline`.** `noinline` is the last-resort hammer.\r\n\r\n#### Strategy 3 — Keep the implementation private to the `.cpp` file\r\n\r\nA function body defined inside a class declaration (or marked `inline` in a header) is implicitly inline: every TU that includes the header parses the body and instantiates every template it touches, even TUs that never call the function. Moving the body to the `.cpp` file pays each cost exactly once. This matters most when the inline body uses STL algorithms or other heavily templated code — each `#include` of the header re-instantiates those templates.\r\n\r\n**Anti-pattern — body defined inline in the header:**\r\n\r\n```cpp\r\n\u002F\u002F ----- foo.h -----\r\n#include \u003Calgorithm>   \u002F\u002F ← every consumer of foo.h pays for \u003Calgorithm>\r\n#include \u003Cstring>\r\n\r\nclass foo\r\n{\r\n    foo(std::string str)\r\n    {\r\n        std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\r\n        \u002F\u002F std::find_if is instantiated in EVERY TU that includes foo.h.\r\n    }\r\n    void bar();\r\n};\r\n\r\n\u002F\u002F ----- foo.cpp -----\r\n#include \"foo.h\"\r\nvoid foo::bar() { }\r\n```\r\n\r\n**Refactored — implementation private to `foo.cpp`:**\r\n\r\n```cpp\r\n\u002F\u002F ----- foo.h -----\r\n#include \u003Cstring>\r\n\r\nclass foo\r\n{\r\n    foo(std::string str);   \u002F\u002F declaration only\r\n    void bar();\r\n};\r\n\r\n\u002F\u002F ----- foo.cpp -----\r\n#include \"foo.h\"\r\n#include \u003Calgorithm>   \u002F\u002F ← only foo.cpp pays for \u003Calgorithm> now\r\n\r\nfoo::foo(std::string str)\r\n{\r\n    std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\r\n}\r\n\r\nvoid foo::bar() { }\r\n```\r\n\r\n`\u003Calgorithm>` and the `std::find_if` instantiation now occur once instead of once per TU. Combine with **Headers — Strategy 2 (forward declarations)** to push more includes from `.h` to `.cpp`.\r\n\r\nApply when an inline header-defined body references heavy templated code (`\u003Calgorithm>`, `\u003Cregex>`, `\u003Cformat>`, `\u003Cranges>`, `\u003Cfilesystem>`, `\u003Cchrono>`) and the header is widely included. Skip for trivial accessors and templates themselves (their definitions must stay visible — use explicit instantiation, Strategy 1 step 5).\r\n\r\n---\r\n\r\n### Expensive Templates (`Templates`)\r\n\r\nTemplates with high WCTR and high instantiation counts cause the compiler to repeat work across many TUs. Reminder: template WCTR is in **microseconds** (`wallClockMicrosecondTimeResponsibility`); only the top **15** entries are considered.\r\n\r\n#### Strategy 1 — Reduce instantiation count\r\n\r\n1. Check `instantiationCount` — thousands of instantiations of the same template are a red flag.\r\n2. Identify whether the high count is from a project template or a standard library template (e.g. `std::vector`, `std::unordered_map`).\r\n3. For **project templates**: limit distinct template arguments. Consider type-erased wrappers or base classes to reduce unique instantiations.\r\n4. For **STL templates**: typically unavoidable but mitigated by PCH (see above) since the compiler caches template definitions from precompiled headers.\r\n\r\n#### Strategy 2 — Explicit template instantiation\r\n\r\nFor project templates instantiated with a known, finite set of types:\r\n\r\n1. Declare the template as `extern` in the header:\r\n   ```cpp\r\n   \u002F\u002F widget.hpp\r\n   template\u003Ctypename T> class Widget { \u002F* ... *\u002F };\r\n   extern template class Widget\u003Cint>;\r\n   extern template class Widget\u003Cfloat>;\r\n   ```\r\n2. Provide explicit instantiations in one `.cpp` file:\r\n   ```cpp\r\n   \u002F\u002F widget.cpp\r\n   template class Widget\u003Cint>;\r\n   template class Widget\u003Cfloat>;\r\n   ```\r\n3. Each instantiation is now compiled once rather than in every TU that uses it.\r\n\r\n#### Strategy 3 — Move template definitions out of headers\r\n\r\n1. If a template's implementation is large, keep only the declaration in the header and move the definition to a `.inl` or `.tpp` file included only where needed.\r\n2. For templates used in only a few TUs, move the full definition to a `.cpp` file with explicit instantiations.\r\n\r\n#### Strategy 4 — Simplify template metaprogramming\r\n\r\n1. Templates with deep recursion or heavy SFINAE\u002F`std::enable_if` are expensive to instantiate.\r\n2. Prefer C++17 `if constexpr` over SFINAE for compile-time branching.\r\n3. Prefer C++20 concepts over complex `std::enable_if` chains.\r\n4. Reduce template nesting depth — flatten helper hierarchies.\r\n\r\n---\r\n\r\n### General Optimization Checklist\r\n\r\nAfter profiling and before making changes, run through this checklist:\r\n\r\n1. **Quick wins (minutes, high impact):**\r\n   - Remove umbrella\u002Fcatch-all includes from widely-included headers.\r\n   - Create or fix PCH with STL + **Tier-2 third-party umbrella headers** (any heavily-included third-party \"include everything\" header your project uses). Missing these is a common cause of an under-performing PCH in projects built around third-party umbrella libraries.\r\n   - Add stable, widely-included project headers to the PCH (see Strategy 1's PCH header selection tiers above).\r\n\r\n2. **Medium effort (hours, moderate impact):**\r\n   - Add forward declarations to headers that only use pointer\u002Freference types.\r\n   - Move large inline functions from headers to `.cpp` files.\r\n   - Use explicit template instantiation for common specializations.\r\n\r\n3. **Larger refactors (days, lower marginal impact):**\r\n   - Split large TUs into smaller files.\r\n   - Flatten deep include chains.\r\n   - Replace heavy template metaprogramming with simpler alternatives.\r\n\r\nAlways re-profile after each round of changes to measure improvement and confirm no regressions.\r\n\r\n---\r\n\r\n## Measuring Final Performance Improvement\r\n\r\nThis section defines **only the post-measurement decision logic and report format**. Measurement procedures live in [Baseline Measurement](#baseline-measurement) and [Iterative Build Measurement](#iterative-build-measurement)\r\n\r\n### When to additionally run iterative measurement\r\n\r\nAfter re-running a clean rebuild against the modified project, **skip iterative measurement when the clean rebuild already shows a statistically significant improvement** — it adds 10+ extra timed builds and confirms nothing new.\r\n\r\nOtherwise, also run [Iterative Build Measurement](#iterative-build-measurement) when **all** of the following are true:\r\n\r\n1. The change added upfront compilation cost — specifically a **PCH** or shared explicit template instantiation.\r\n2. The clean-rebuild result is neutral, regressed, or within `baseline_average ± baseline_stddev`.\r\n3. The change is theoretically sound based on the JSON analysis (e.g., a header used in many TUs was moved into a PCH and *should* amortize across iterative edits).\r\n\r\nA change is a **net win** if either the clean-rebuild OR the iterative result is statistically significant and the other is at worst neutral.\r\n\r\n### Summary format\r\n\r\n**When validation ran**, report all times in seconds with mean and standard deviation in **separate columns** — do not use the `mean ± stddev` shorthand. Include both measurements when iterative ran. If you tried an approach that did not work and switched strategies, briefly state what you tried and why you moved on.\r\n\r\n| Measurement | Variant | Mean (s) | StdDev (s) | Delta % |\r\n|---|---|---|---|---|\r\n| Clean rebuild | baseline | 45.2 | 1.8 | |\r\n| Clean rebuild | post | 47.1 | 1.5 | -4.2% (regression) |\r\n| Iterative build | baseline | 8.4 | 0.3 | |\r\n| Iterative build | post | 3.1 | 0.2 | +63.1% (significant) |\r\n\r\nDecision: keep change — large iterative win outweighs small rebuild regression.",{"data":34,"body":36},{"name":4,"description":6,"compatibility":35},"Windows with MSVC toolchain. Requires administrator privileges for default tracing.",{"type":37,"children":38},"root",[39,48,55,69,76,86,188,194,231,262,288,294,322,465,483,489,494,499,517,557,569,611,617,627,635,667,688,698,721,739,747,753,771,781,793,799,811,968,1012,1018,1051,1176,1207,1213,1240,1295,1315,1321,1326,1384,1389,1421,1479,1485,1494,1606,1618,1624,1652,1671,1678,1714,1741,1747,1756,1761,1770,1776,1829,1849,1857,1958,1966,2038,2072,2098,2114,2153,2171,2176,2181,2205,2213,2242,2250,2259,2265,2304,2308,2313,2324,2347,2357,2363,2478,2483,2494,2500,2512,2535,2548,2554,2566,2596,2663,2669,2674,2712,2718,2749,2754,2823,2842,2848,2875,2935,2955,2961,2977,2988,3006,3011,3030,3043,3048,3054,3059,3067,3119,3127,3146,3154,3298,3308,3314,3319,3398,3404,3409,3433,3436,3448,3453,3467,3479,3584,3590,3595,3659,3672,3699,3707,3854,3869,4019,4058,4105,4108,4120,4146,4152,4211,4217,4222,4325,4331,4366,4372,4418,4421,4427,4432,4527,4532,4535,4540,4561,4567,4579,4597,4636,4648,4654,4678,4816,4821],{"type":40,"tag":41,"props":42,"children":44},"element","h1",{"id":43},"build-performance-analysis-with-vcperfexe",[45],{"type":46,"value":47},"text","Build Performance Analysis with vcperf.exe",{"type":40,"tag":49,"props":50,"children":52},"h2",{"id":51},"execution-order",[53],{"type":46,"value":54},"Execution order",{"type":40,"tag":56,"props":57,"children":58},"p",{},[59,61,67],{"type":46,"value":60},"A single ",{"type":40,"tag":62,"props":63,"children":64},"strong",{},[65],{"type":46,"value":66},"workflow",{"type":46,"value":68},", always run in order.",{"type":40,"tag":70,"props":71,"children":73},"h3",{"id":72},"workflow-always-run-in-order",[74],{"type":46,"value":75},"Workflow — always run, in order",{"type":40,"tag":56,"props":77,"children":78},{},[79,84],{"type":40,"tag":62,"props":80,"children":81},{},[82],{"type":46,"value":83},"Treat each session as independent.",{"type":46,"value":85}," Re-capture traces, JSON analysis, and baseline measurements fresh each session instead of reusing data from a previous session — the one-time trace-permission grant persists.",{"type":40,"tag":87,"props":88,"children":89},"ol",{},[90,110,127,152,170],{"type":40,"tag":91,"props":92,"children":93},"li",{},[94,101,103,108],{"type":40,"tag":95,"props":96,"children":98},"a",{"href":97},"#prerequisites-trace-permission",[99],{"type":46,"value":100},"Prerequisites: Trace Permission",{"type":46,"value":102}," — grant ETW rights. Run ",{"type":40,"tag":62,"props":104,"children":105},{},[106],{"type":46,"value":107},"before",{"type":46,"value":109}," any workspace exploration (project enumeration, file listing, code search).",{"type":40,"tag":91,"props":111,"children":112},{},[113,119,121],{"type":40,"tag":95,"props":114,"children":116},{"href":115},"#core-workflow",[117],{"type":46,"value":118},"Core Workflow",{"type":46,"value":120}," + ",{"type":40,"tag":95,"props":122,"children":124},{"href":123},"#the-jsonanalysis-flag",[125],{"type":46,"value":126},"The \u002FjsonAnalysis Flag",{"type":40,"tag":91,"props":128,"children":129},{},[130,136,138,143,145,150],{"type":40,"tag":95,"props":131,"children":133},{"href":132},"#baseline-measurement",[134],{"type":46,"value":135},"Baseline Measurement",{"type":46,"value":137}," — 5 uninstrumented clean rebuilds of the ",{"type":40,"tag":62,"props":139,"children":140},{},[141],{"type":46,"value":142},"pre-change",{"type":46,"value":144}," state; average for a stable baseline. ",{"type":40,"tag":62,"props":146,"children":147},{},[148],{"type":46,"value":149},"Make no code or project edits during this step",{"type":46,"value":151},".",{"type":40,"tag":91,"props":153,"children":154},{},[155,161,163,168],{"type":40,"tag":95,"props":156,"children":158},{"href":157},"#remediation-strategies",[159],{"type":46,"value":160},"Remediation Strategies",{"type":46,"value":162}," — the ",{"type":40,"tag":62,"props":164,"children":165},{},[166],{"type":46,"value":167},"first",{"type":46,"value":169}," step where you edit anything; apply changes informed by Steps 2–3.",{"type":40,"tag":91,"props":171,"children":172},{},[173,179,181,187],{"type":40,"tag":95,"props":174,"children":176},{"href":175},"#measuring-final-performance-improvement",[177],{"type":46,"value":178},"Measuring Final Performance Improvement",{"type":46,"value":180}," — 5 uninstrumented clean rebuilds of the post-change state; compare against the baseline. If a PCH or template change shows a neutral or regressed delta, also run ",{"type":40,"tag":95,"props":182,"children":184},{"href":183},"#iterative-build-measurement",[185],{"type":46,"value":186},"Iterative Build Measurement",{"type":46,"value":151},{"type":40,"tag":49,"props":189,"children":191},{"id":190},"which-vcperfexe-executable-should-i-use",[192],{"type":46,"value":193},"Which vcperf.exe executable should I use?",{"type":40,"tag":56,"props":195,"children":196},{},[197,199,206,208,214,216,222,224,229],{"type":46,"value":198},"The ",{"type":40,"tag":200,"props":201,"children":203},"code",{"className":202},[],[204],{"type":46,"value":205},"sessionStart",{"type":46,"value":207}," hook installs ",{"type":40,"tag":200,"props":209,"children":211},{"className":210},[],[212],{"type":46,"value":213},"vcperf.exe",{"type":46,"value":215}," under ",{"type":40,"tag":200,"props":217,"children":219},{"className":218},[],[220],{"type":46,"value":221},"%LOCALAPPDATA%\\vcperf\\build-perf-cpp",{"type":46,"value":223}," (multiple versions may coexist). Resolve the ",{"type":40,"tag":62,"props":225,"children":226},{},[227],{"type":46,"value":228},"newest",{"type":46,"value":230}," version once and reuse it:",{"type":40,"tag":232,"props":233,"children":238},"pre",{"className":234,"code":235,"language":236,"meta":237,"style":237},"language-powershell shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$vcperfPkg = Get-ChildItem \"$env:LOCALAPPDATA\\vcperf\\build-perf-cpp\" -Directory -Filter 'Microsoft.Cpp.vcperf.*' -ErrorAction SilentlyContinue | Sort-Object { ($_.Name -replace '^Microsoft\\.Cpp\\.vcperf\\.', '' -split '\\.' | ForEach-Object { ([long]$_).ToString().PadLeft(20, '0') }) -join '.' } -Descending | Select-Object -First 1\n$vcperf = if ($vcperfPkg) { (Get-ChildItem $vcperfPkg.FullName -Recurse -Filter vcperf.exe | Where-Object DirectoryName -like '*\\x64' | Select-Object -First 1).FullName }\n","powershell","",[239],{"type":40,"tag":200,"props":240,"children":241},{"__ignoreMap":237},[242,253],{"type":40,"tag":243,"props":244,"children":247},"span",{"class":245,"line":246},"line",1,[248],{"type":40,"tag":243,"props":249,"children":250},{},[251],{"type":46,"value":252},"$vcperfPkg = Get-ChildItem \"$env:LOCALAPPDATA\\vcperf\\build-perf-cpp\" -Directory -Filter 'Microsoft.Cpp.vcperf.*' -ErrorAction SilentlyContinue | Sort-Object { ($_.Name -replace '^Microsoft\\.Cpp\\.vcperf\\.', '' -split '\\.' | ForEach-Object { ([long]$_).ToString().PadLeft(20, '0') }) -join '.' } -Descending | Select-Object -First 1\n",{"type":40,"tag":243,"props":254,"children":256},{"class":245,"line":255},2,[257],{"type":40,"tag":243,"props":258,"children":259},{},[260],{"type":46,"value":261},"$vcperf = if ($vcperfPkg) { (Get-ChildItem $vcperfPkg.FullName -Recurse -Filter vcperf.exe | Where-Object DirectoryName -like '*\\x64' | Select-Object -First 1).FullName }\n",{"type":40,"tag":56,"props":263,"children":264},{},[265,270,272,278,280,286],{"type":40,"tag":62,"props":266,"children":267},{},[268],{"type":46,"value":269},"Authentication",{"type":46,"value":271},": If ",{"type":40,"tag":200,"props":273,"children":275},{"className":274},[],[276],{"type":46,"value":277},"$vcperf",{"type":46,"value":279}," resolves empty, read ",{"type":40,"tag":200,"props":281,"children":283},{"className":282},[],[284],{"type":46,"value":285},"references\u002Ffeed-auth.md",{"type":46,"value":287}," and follow it before proceeding.",{"type":40,"tag":70,"props":289,"children":291},{"id":290},"invocation-rule-read-before-running-any-vcperf-command",[292],{"type":46,"value":293},"Invocation rule (read before running any vcperf command)",{"type":40,"tag":56,"props":295,"children":296},{},[297,299,305,307,312,314,320],{"type":46,"value":298},"Every ",{"type":40,"tag":200,"props":300,"children":302},{"className":301},[],[303],{"type":46,"value":304},"vcperf",{"type":46,"value":306}," command below runs the resolved ",{"type":40,"tag":200,"props":308,"children":310},{"className":309},[],[311],{"type":46,"value":277},{"type":46,"value":313}," path directly in PowerShell (",{"type":40,"tag":200,"props":315,"children":317},{"className":316},[],[318],{"type":46,"value":319},"& $vcperf ...",{"type":46,"value":321},"). Both rules are mandatory:",{"type":40,"tag":87,"props":323,"children":324},{},[325,377],{"type":40,"tag":91,"props":326,"children":327},{},[328,346,348,353,355,361,363,369,371,376],{"type":40,"tag":62,"props":329,"children":330},{},[331,333,338,340,345],{"type":46,"value":332},"Use the absolute ",{"type":40,"tag":200,"props":334,"children":336},{"className":335},[],[337],{"type":46,"value":277},{"type":46,"value":339}," path, never a bare ",{"type":40,"tag":200,"props":341,"children":343},{"className":342},[],[344],{"type":46,"value":304},{"type":46,"value":151},{"type":46,"value":347}," Bare ",{"type":40,"tag":200,"props":349,"children":351},{"className":350},[],[352],{"type":46,"value":304},{"type":46,"value":354}," resolves off ",{"type":40,"tag":200,"props":356,"children":358},{"className":357},[],[359],{"type":46,"value":360},"PATH",{"type":46,"value":362}," to the older Visual-Studio-bundled copy (may lack ",{"type":40,"tag":200,"props":364,"children":366},{"className":365},[],[367],{"type":46,"value":368},"\u002FjsonAnalysis",{"type":46,"value":370},"), not the one under ",{"type":40,"tag":200,"props":372,"children":374},{"className":373},[],[375],{"type":46,"value":221},{"type":46,"value":151},{"type":40,"tag":91,"props":378,"children":379},{},[380,392,394,400,402,408,410,416,418,423,425,431,433,439,441,447,449,455,457,463],{"type":40,"tag":62,"props":381,"children":382},{},[383,385,391],{"type":46,"value":384},"Judge success by the output file, not ",{"type":40,"tag":200,"props":386,"children":388},{"className":387},[],[389],{"type":46,"value":390},"$LASTEXITCODE",{"type":46,"value":151},{"type":46,"value":393}," PowerShell's ",{"type":40,"tag":200,"props":395,"children":397},{"className":396},[],[398],{"type":46,"value":399},"& $vcperf",{"type":46,"value":401}," can surface an internal COM ",{"type":40,"tag":200,"props":403,"children":405},{"className":404},[],[406],{"type":46,"value":407},"HRESULT",{"type":46,"value":409}," (e.g. ",{"type":40,"tag":200,"props":411,"children":413},{"className":412},[],[414],{"type":46,"value":415},"0x80040013",{"type":46,"value":417},") in ",{"type":40,"tag":200,"props":419,"children":421},{"className":420},[],[422],{"type":46,"value":390},{"type":46,"value":424}," and render output as blank lines, so a run that actually succeeded can look failed. After a ",{"type":40,"tag":200,"props":426,"children":428},{"className":427},[],[429],{"type":46,"value":430},"\u002Fstop",{"type":46,"value":432}," or ",{"type":40,"tag":200,"props":434,"children":436},{"className":435},[],[437],{"type":46,"value":438},"\u002Fstopnoanalyze",{"type":46,"value":440},", confirm the expected ",{"type":40,"tag":200,"props":442,"children":444},{"className":443},[],[445],{"type":46,"value":446},".etl",{"type":46,"value":448},"\u002F",{"type":40,"tag":200,"props":450,"children":452},{"className":451},[],[453],{"type":46,"value":454},".json",{"type":46,"value":456}," file was written (",{"type":40,"tag":200,"props":458,"children":460},{"className":459},[],[461],{"type":46,"value":462},"Test-Path",{"type":46,"value":464},") instead of trusting the exit code.",{"type":40,"tag":56,"props":466,"children":467},{},[468,470,475,477,481],{"type":46,"value":469},"The command blocks in ",{"type":40,"tag":95,"props":471,"children":472},{"href":97},[473],{"type":46,"value":474},"Prerequisites",{"type":46,"value":476}," and ",{"type":40,"tag":95,"props":478,"children":479},{"href":115},[480],{"type":46,"value":118},{"type":46,"value":482}," below apply both rules — follow their exact form.",{"type":40,"tag":49,"props":484,"children":486},{"id":485},"what-is-vcperf",[487],{"type":46,"value":488},"What is vcperf?",{"type":40,"tag":56,"props":490,"children":491},{},[492],{"type":46,"value":493},"vcperf.exe captures and analyzes C++ build traces using the C++ Build Insights SDK. It records ETW events during MSVC compilations and produces either ETL files (for Windows Performance Analyzer) or structured JSON reports.",{"type":40,"tag":49,"props":495,"children":497},{"id":496},"prerequisites-trace-permission",[498],{"type":46,"value":100},{"type":40,"tag":56,"props":500,"children":501},{},[502,508,510,515],{"type":40,"tag":200,"props":503,"children":505},{"className":504},[],[506],{"type":46,"value":507},"vcperf \u002Fstart",{"type":46,"value":509}," writes ETW providers that require ",{"type":40,"tag":62,"props":511,"children":512},{},[513],{"type":46,"value":514},"either",{"type":46,"value":516},":",{"type":40,"tag":518,"props":519,"children":520},"ul",{},[521,533],{"type":40,"tag":91,"props":522,"children":523},{},[524,526,531],{"type":46,"value":525},"the invoking process to be ",{"type":40,"tag":62,"props":527,"children":528},{},[529],{"type":46,"value":530},"elevated (Administrator)",{"type":46,"value":532},", OR",{"type":40,"tag":91,"props":534,"children":535},{},[536,538,547,549,555],{"type":46,"value":537},"a one-time ",{"type":40,"tag":62,"props":539,"children":540},{},[541],{"type":40,"tag":200,"props":542,"children":544},{"className":543},[],[545],{"type":46,"value":546},"vcperf \u002Fgrantusercontrol",{"type":46,"value":548}," run elevated for the current user — after which non-admin invocations may use ",{"type":40,"tag":200,"props":550,"children":552},{"className":551},[],[553],{"type":46,"value":554},"\u002Fstart \u002Fnoadmin",{"type":46,"value":556}," (reduced data: no CPU sampling).",{"type":40,"tag":56,"props":558,"children":559},{},[560,562,567],{"type":46,"value":561},"The CLI agent runs unelevated and ",{"type":40,"tag":62,"props":563,"children":564},{},[565],{"type":46,"value":566},"must solve this itself",{"type":46,"value":568}," — do not ask the user to \"open an elevated prompt and run X by hand\".",{"type":40,"tag":56,"props":570,"children":571},{},[572,574,579,581,601,603,609],{"type":46,"value":573},"Run on first use. Once Step 4 verifies the grant, Step 4b persists a per-user marker file so ",{"type":40,"tag":62,"props":575,"children":576},{},[577],{"type":46,"value":578},"future sessions skip Trace Permission Steps 2–4 entirely",{"type":46,"value":580},". Within a session, also cache the Step 1 result in working memory. ",{"type":40,"tag":62,"props":582,"children":583},{},[584,586,592,593,599],{"type":46,"value":585},"Skip entirely for ",{"type":40,"tag":200,"props":587,"children":589},{"className":588},[],[590],{"type":46,"value":591},"vcperf \u002Fanalyze",{"type":46,"value":476},{"type":40,"tag":200,"props":594,"children":596},{"className":595},[],[597],{"type":46,"value":598},"vcperf \u002Fstop",{"type":46,"value":600}," against an existing trace",{"type":46,"value":602}," — only ",{"type":40,"tag":200,"props":604,"children":606},{"className":605},[],[607],{"type":46,"value":608},"\u002Fstart",{"type":46,"value":610}," needs the grant.",{"type":40,"tag":70,"props":612,"children":614},{"id":613},"step-1-check-whether-rights-already-exist",[615],{"type":46,"value":616},"Step 1 — Check whether rights already exist",{"type":40,"tag":56,"props":618,"children":619},{},[620,622],{"type":46,"value":621},"Two signals; either is sufficient. ",{"type":40,"tag":62,"props":623,"children":624},{},[625],{"type":46,"value":626},"Run Check A first; skip Check B if A is true.",{"type":40,"tag":56,"props":628,"children":629},{},[630],{"type":40,"tag":62,"props":631,"children":632},{},[633],{"type":46,"value":634},"Check A — process is elevated:",{"type":40,"tag":232,"props":636,"children":638},{"className":234,"code":637,"language":236,"meta":237,"style":237},"$isAdmin = ([Security.Principal.WindowsPrincipal]::new(\n    [Security.Principal.WindowsIdentity]::GetCurrent())\n).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)\n",[639],{"type":40,"tag":200,"props":640,"children":641},{"__ignoreMap":237},[642,650,658],{"type":40,"tag":243,"props":643,"children":644},{"class":245,"line":246},[645],{"type":40,"tag":243,"props":646,"children":647},{},[648],{"type":46,"value":649},"$isAdmin = ([Security.Principal.WindowsPrincipal]::new(\n",{"type":40,"tag":243,"props":651,"children":652},{"class":245,"line":255},[653],{"type":40,"tag":243,"props":654,"children":655},{},[656],{"type":46,"value":657},"    [Security.Principal.WindowsIdentity]::GetCurrent())\n",{"type":40,"tag":243,"props":659,"children":661},{"class":245,"line":660},3,[662],{"type":40,"tag":243,"props":663,"children":664},{},[665],{"type":46,"value":666},").IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)\n",{"type":40,"tag":56,"props":668,"children":669},{},[670,672,678,680,686],{"type":46,"value":671},"If ",{"type":40,"tag":200,"props":673,"children":675},{"className":674},[],[676],{"type":46,"value":677},"$isAdmin",{"type":46,"value":679}," is ",{"type":40,"tag":200,"props":681,"children":683},{"className":682},[],[684],{"type":46,"value":685},"$true",{"type":46,"value":687}," → skip to Step 5.",{"type":40,"tag":56,"props":689,"children":690},{},[691,696],{"type":40,"tag":62,"props":692,"children":693},{},[694],{"type":46,"value":695},"Check B — agent-persisted grant marker",{"type":46,"value":697}," (only when Check A is false):",{"type":40,"tag":232,"props":699,"children":701},{"className":234,"code":700,"language":236,"meta":237,"style":237},"$grantMarker = Join-Path $env:LOCALAPPDATA 'vcperf\\grant-verified'\n$hasGrantMarker = Test-Path -LiteralPath $grantMarker -PathType Leaf\n\n",[702],{"type":40,"tag":200,"props":703,"children":704},{"__ignoreMap":237},[705,713],{"type":40,"tag":243,"props":706,"children":707},{"class":245,"line":246},[708],{"type":40,"tag":243,"props":709,"children":710},{},[711],{"type":46,"value":712},"$grantMarker = Join-Path $env:LOCALAPPDATA 'vcperf\\grant-verified'\n",{"type":40,"tag":243,"props":714,"children":715},{"class":245,"line":255},[716],{"type":40,"tag":243,"props":717,"children":718},{},[719],{"type":46,"value":720},"$hasGrantMarker = Test-Path -LiteralPath $grantMarker -PathType Leaf\n",{"type":40,"tag":56,"props":722,"children":723},{},[724,725,731,732,737],{"type":46,"value":671},{"type":40,"tag":200,"props":726,"children":728},{"className":727},[],[729],{"type":46,"value":730},"$hasGrantMarker",{"type":46,"value":679},{"type":40,"tag":200,"props":733,"children":735},{"className":734},[],[736],{"type":46,"value":685},{"type":46,"value":738},", the agent already granted and verified rights in a previous session — proceed without re-prompting.",{"type":40,"tag":56,"props":740,"children":741},{},[742],{"type":40,"tag":62,"props":743,"children":744},{},[745],{"type":46,"value":746},"If Check A OR Check B is true → you have rights. Skip to Step 5.",{"type":40,"tag":70,"props":748,"children":750},{"id":749},"step-2-ask-the-user-before-triggering-uac-required",[751],{"type":46,"value":752},"Step 2 — Ask the user before triggering UAC (REQUIRED)",{"type":40,"tag":56,"props":754,"children":755},{},[756,758],{"type":46,"value":757},"If neither check is true, you MUST get explicit consent before launching an elevated process. ",{"type":40,"tag":62,"props":759,"children":760},{},[761,763,769],{"type":46,"value":762},"Use the ",{"type":40,"tag":200,"props":764,"children":766},{"className":765},[],[767],{"type":46,"value":768},"ask_user",{"type":46,"value":770}," tool — never just print prompt text in chat.",{"type":40,"tag":232,"props":772,"children":776},{"className":773,"code":775,"language":46},[774],"language-text","ask_user(\n  question = \"vcperf needs additional permissions to execute a trace. May I run a one-time elevated `vcperf \u002Fgrantusercontrol`? A UAC prompt will appear.\",\n  choices  = [\"Yes (Recommended)\", \"No\"]\n)\n",[777],{"type":40,"tag":200,"props":778,"children":779},{"__ignoreMap":237},[780],{"type":46,"value":775},{"type":40,"tag":56,"props":782,"children":783},{},[784,786,791],{"type":46,"value":785},"If the user answers ",{"type":40,"tag":62,"props":787,"children":788},{},[789],{"type":46,"value":790},"No",{"type":46,"value":792},", stop the workflow. Report that vcperf cannot run without trace permission and let the user decide how to proceed. Do NOT fall through to Step 3, do not retry, and do not silently downgrade to a non-vcperf measurement.",{"type":40,"tag":70,"props":794,"children":796},{"id":795},"step-3-grant-rights-elevated",[797],{"type":46,"value":798},"Step 3 — Grant rights elevated",{"type":40,"tag":56,"props":800,"children":801},{},[802,804,809],{"type":46,"value":803},"Launch an elevated PowerShell that runs ",{"type":40,"tag":200,"props":805,"children":807},{"className":806},[],[808],{"type":46,"value":546},{"type":46,"value":810}," and wait for it. The grant produces no output artifact, so Step 4 verifies it functionally:",{"type":40,"tag":232,"props":812,"children":814},{"className":234,"code":813,"language":236,"meta":237,"style":237},"# $vcperf must already hold the absolute path (see resolution block above).\n# \u002Fgrantusercontrol writes no output file, so Step 4 verifies it functionally;\n# we don't depend on vcperf's exit code here (see Invocation rule).\ntry {\n    Start-Process powershell.exe `\n        -ArgumentList '-NoProfile','-Command',\"& '$vcperf' \u002Fgrantusercontrol\" `\n        -Verb RunAs -Wait\n    $grantCancelled = $false\n} catch [System.ComponentModel.Win32Exception] {\n    if ($_.Exception.NativeErrorCode -eq 1223) {\n        # Win32 error 1223 = ERROR_CANCELLED — user dismissed the UAC prompt.\n        $grantCancelled = $true\n    } else {\n        throw\n    }\n}\n$grantCancelled\n",[815],{"type":40,"tag":200,"props":816,"children":817},{"__ignoreMap":237},[818,826,834,842,851,860,869,878,887,896,905,914,923,932,941,950,959],{"type":40,"tag":243,"props":819,"children":820},{"class":245,"line":246},[821],{"type":40,"tag":243,"props":822,"children":823},{},[824],{"type":46,"value":825},"# $vcperf must already hold the absolute path (see resolution block above).\n",{"type":40,"tag":243,"props":827,"children":828},{"class":245,"line":255},[829],{"type":40,"tag":243,"props":830,"children":831},{},[832],{"type":46,"value":833},"# \u002Fgrantusercontrol writes no output file, so Step 4 verifies it functionally;\n",{"type":40,"tag":243,"props":835,"children":836},{"class":245,"line":660},[837],{"type":40,"tag":243,"props":838,"children":839},{},[840],{"type":46,"value":841},"# we don't depend on vcperf's exit code here (see Invocation rule).\n",{"type":40,"tag":243,"props":843,"children":845},{"class":245,"line":844},4,[846],{"type":40,"tag":243,"props":847,"children":848},{},[849],{"type":46,"value":850},"try {\n",{"type":40,"tag":243,"props":852,"children":854},{"class":245,"line":853},5,[855],{"type":40,"tag":243,"props":856,"children":857},{},[858],{"type":46,"value":859},"    Start-Process powershell.exe `\n",{"type":40,"tag":243,"props":861,"children":863},{"class":245,"line":862},6,[864],{"type":40,"tag":243,"props":865,"children":866},{},[867],{"type":46,"value":868},"        -ArgumentList '-NoProfile','-Command',\"& '$vcperf' \u002Fgrantusercontrol\" `\n",{"type":40,"tag":243,"props":870,"children":872},{"class":245,"line":871},7,[873],{"type":40,"tag":243,"props":874,"children":875},{},[876],{"type":46,"value":877},"        -Verb RunAs -Wait\n",{"type":40,"tag":243,"props":879,"children":881},{"class":245,"line":880},8,[882],{"type":40,"tag":243,"props":883,"children":884},{},[885],{"type":46,"value":886},"    $grantCancelled = $false\n",{"type":40,"tag":243,"props":888,"children":890},{"class":245,"line":889},9,[891],{"type":40,"tag":243,"props":892,"children":893},{},[894],{"type":46,"value":895},"} catch [System.ComponentModel.Win32Exception] {\n",{"type":40,"tag":243,"props":897,"children":899},{"class":245,"line":898},10,[900],{"type":40,"tag":243,"props":901,"children":902},{},[903],{"type":46,"value":904},"    if ($_.Exception.NativeErrorCode -eq 1223) {\n",{"type":40,"tag":243,"props":906,"children":908},{"class":245,"line":907},11,[909],{"type":40,"tag":243,"props":910,"children":911},{},[912],{"type":46,"value":913},"        # Win32 error 1223 = ERROR_CANCELLED — user dismissed the UAC prompt.\n",{"type":40,"tag":243,"props":915,"children":917},{"class":245,"line":916},12,[918],{"type":40,"tag":243,"props":919,"children":920},{},[921],{"type":46,"value":922},"        $grantCancelled = $true\n",{"type":40,"tag":243,"props":924,"children":926},{"class":245,"line":925},13,[927],{"type":40,"tag":243,"props":928,"children":929},{},[930],{"type":46,"value":931},"    } else {\n",{"type":40,"tag":243,"props":933,"children":935},{"class":245,"line":934},14,[936],{"type":40,"tag":243,"props":937,"children":938},{},[939],{"type":46,"value":940},"        throw\n",{"type":40,"tag":243,"props":942,"children":944},{"class":245,"line":943},15,[945],{"type":40,"tag":243,"props":946,"children":947},{},[948],{"type":46,"value":949},"    }\n",{"type":40,"tag":243,"props":951,"children":953},{"class":245,"line":952},16,[954],{"type":40,"tag":243,"props":955,"children":956},{},[957],{"type":46,"value":958},"}\n",{"type":40,"tag":243,"props":960,"children":962},{"class":245,"line":961},17,[963],{"type":40,"tag":243,"props":964,"children":965},{},[966],{"type":46,"value":967},"$grantCancelled\n",{"type":40,"tag":518,"props":969,"children":970},{},[971,1000],{"type":40,"tag":91,"props":972,"children":973},{},[974,976,982,984,990,992,998],{"type":46,"value":975},"A UAC dialog will appear. If the user cancels it, ",{"type":40,"tag":200,"props":977,"children":979},{"className":978},[],[980],{"type":46,"value":981},"Start-Process -Verb RunAs",{"type":46,"value":983}," throws ",{"type":40,"tag":200,"props":985,"children":987},{"className":986},[],[988],{"type":46,"value":989},"Win32Exception",{"type":46,"value":991}," with ",{"type":40,"tag":200,"props":993,"children":995},{"className":994},[],[996],{"type":46,"value":997},"NativeErrorCode = 1223",{"type":46,"value":999}," — treat that as \"user declined\" and stop (same outcome as a \"No\" in Step 2).",{"type":40,"tag":91,"props":1001,"children":1002},{},[1003,1005,1010],{"type":46,"value":1004},"Otherwise the elevated grant ran. Its exit code is not reliable (see Invocation rule), so ",{"type":40,"tag":62,"props":1006,"children":1007},{},[1008],{"type":46,"value":1009},"Step 4 is the authoritative check",{"type":46,"value":1011}," that the grant actually worked — proceed there.",{"type":40,"tag":70,"props":1013,"children":1015},{"id":1014},"step-4-verify-the-grant-worked",[1016],{"type":46,"value":1017},"Step 4 — Verify the grant worked",{"type":40,"tag":56,"props":1019,"children":1020},{},[1021,1023,1028,1030,1035,1037,1042,1044,1049],{"type":46,"value":1022},"Do not trust Step 3 alone — run a functional probe. Use ",{"type":40,"tag":200,"props":1024,"children":1026},{"className":1025},[],[1027],{"type":46,"value":438},{"type":46,"value":1029}," (not ",{"type":40,"tag":200,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":46,"value":430},{"type":46,"value":1036},"); the probe only needs to prove ",{"type":40,"tag":200,"props":1038,"children":1040},{"className":1039},[],[1041],{"type":46,"value":554},{"type":46,"value":1043}," succeeded, and ",{"type":40,"tag":200,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":46,"value":430},{"type":46,"value":1050}," would waste seconds analyzing an empty session.",{"type":40,"tag":232,"props":1052,"children":1054},{"className":234,"code":1053,"language":236,"meta":237,"style":237},"$probe   = 'PermProbe_' + [guid]::NewGuid().ToString('N').Substring(0,8)\n$probeEtl = Join-Path $env:TEMP \"$probe.etl\"\nRemove-Item $probeEtl -ErrorAction SilentlyContinue\n# Success signal is whether the probe ETL is produced, not $LASTEXITCODE\n# (see Invocation rule). A working \u002Fstart + \u002Fstopnoanalyze writes the ETL;\n# if \u002Fstart was denied, no ETL appears.\n$startOutput = (& $vcperf \u002Fstart \u002Fnoadmin $probe *>&1 | Out-String).Trim()\n$stopOutput = (& $vcperf \u002Fstopnoanalyze $probe $probeEtl *>&1 | Out-String).Trim()\n$started = Test-Path $probeEtl\nif (-not $started) {\n    $probeOutput = @($startOutput, $stopOutput) | Where-Object { $_ }\n    Write-Error (\"vcperf permission probe failed.`n\" + ($probeOutput -join \"`n\"))\n}\nRemove-Item $probeEtl -ErrorAction SilentlyContinue\n$started\n",[1055],{"type":40,"tag":200,"props":1056,"children":1057},{"__ignoreMap":237},[1058,1066,1074,1082,1090,1098,1106,1114,1122,1130,1138,1146,1154,1161,1168],{"type":40,"tag":243,"props":1059,"children":1060},{"class":245,"line":246},[1061],{"type":40,"tag":243,"props":1062,"children":1063},{},[1064],{"type":46,"value":1065},"$probe   = 'PermProbe_' + [guid]::NewGuid().ToString('N').Substring(0,8)\n",{"type":40,"tag":243,"props":1067,"children":1068},{"class":245,"line":255},[1069],{"type":40,"tag":243,"props":1070,"children":1071},{},[1072],{"type":46,"value":1073},"$probeEtl = Join-Path $env:TEMP \"$probe.etl\"\n",{"type":40,"tag":243,"props":1075,"children":1076},{"class":245,"line":660},[1077],{"type":40,"tag":243,"props":1078,"children":1079},{},[1080],{"type":46,"value":1081},"Remove-Item $probeEtl -ErrorAction SilentlyContinue\n",{"type":40,"tag":243,"props":1083,"children":1084},{"class":245,"line":844},[1085],{"type":40,"tag":243,"props":1086,"children":1087},{},[1088],{"type":46,"value":1089},"# Success signal is whether the probe ETL is produced, not $LASTEXITCODE\n",{"type":40,"tag":243,"props":1091,"children":1092},{"class":245,"line":853},[1093],{"type":40,"tag":243,"props":1094,"children":1095},{},[1096],{"type":46,"value":1097},"# (see Invocation rule). A working \u002Fstart + \u002Fstopnoanalyze writes the ETL;\n",{"type":40,"tag":243,"props":1099,"children":1100},{"class":245,"line":862},[1101],{"type":40,"tag":243,"props":1102,"children":1103},{},[1104],{"type":46,"value":1105},"# if \u002Fstart was denied, no ETL appears.\n",{"type":40,"tag":243,"props":1107,"children":1108},{"class":245,"line":871},[1109],{"type":40,"tag":243,"props":1110,"children":1111},{},[1112],{"type":46,"value":1113},"$startOutput = (& $vcperf \u002Fstart \u002Fnoadmin $probe *>&1 | Out-String).Trim()\n",{"type":40,"tag":243,"props":1115,"children":1116},{"class":245,"line":880},[1117],{"type":40,"tag":243,"props":1118,"children":1119},{},[1120],{"type":46,"value":1121},"$stopOutput = (& $vcperf \u002Fstopnoanalyze $probe $probeEtl *>&1 | Out-String).Trim()\n",{"type":40,"tag":243,"props":1123,"children":1124},{"class":245,"line":889},[1125],{"type":40,"tag":243,"props":1126,"children":1127},{},[1128],{"type":46,"value":1129},"$started = Test-Path $probeEtl\n",{"type":40,"tag":243,"props":1131,"children":1132},{"class":245,"line":898},[1133],{"type":40,"tag":243,"props":1134,"children":1135},{},[1136],{"type":46,"value":1137},"if (-not $started) {\n",{"type":40,"tag":243,"props":1139,"children":1140},{"class":245,"line":907},[1141],{"type":40,"tag":243,"props":1142,"children":1143},{},[1144],{"type":46,"value":1145},"    $probeOutput = @($startOutput, $stopOutput) | Where-Object { $_ }\n",{"type":40,"tag":243,"props":1147,"children":1148},{"class":245,"line":916},[1149],{"type":40,"tag":243,"props":1150,"children":1151},{},[1152],{"type":46,"value":1153},"    Write-Error (\"vcperf permission probe failed.`n\" + ($probeOutput -join \"`n\"))\n",{"type":40,"tag":243,"props":1155,"children":1156},{"class":245,"line":925},[1157],{"type":40,"tag":243,"props":1158,"children":1159},{},[1160],{"type":46,"value":958},{"type":40,"tag":243,"props":1162,"children":1163},{"class":245,"line":934},[1164],{"type":40,"tag":243,"props":1165,"children":1166},{},[1167],{"type":46,"value":1081},{"type":40,"tag":243,"props":1169,"children":1170},{"class":245,"line":943},[1171],{"type":40,"tag":243,"props":1172,"children":1173},{},[1174],{"type":46,"value":1175},"$started\n",{"type":40,"tag":56,"props":1177,"children":1178},{},[1179,1180,1186,1187,1192,1194,1200,1202],{"type":46,"value":671},{"type":40,"tag":200,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":46,"value":1185},"$started",{"type":46,"value":679},{"type":40,"tag":200,"props":1188,"children":1190},{"className":1189},[],[1191],{"type":46,"value":685},{"type":46,"value":1193},", the grant is verified — proceed. If ",{"type":40,"tag":200,"props":1195,"children":1197},{"className":1196},[],[1198],{"type":46,"value":1199},"$false",{"type":46,"value":1201},", the grant did not take effect — surface the failure with the vcperf output and stop. Do not silently retry. ",{"type":40,"tag":62,"props":1203,"children":1204},{},[1205],{"type":46,"value":1206},"Do NOT run Step 4b on a failed verify.",{"type":40,"tag":70,"props":1208,"children":1210},{"id":1209},"step-4b-persist-the-verified-grant-so-future-sessions-skip-steps-24",[1211],{"type":46,"value":1212},"Step 4b — Persist the verified grant (so future sessions skip Steps 2–4)",{"type":40,"tag":56,"props":1214,"children":1215},{},[1216,1218,1223,1225,1231,1233,1238],{"type":46,"value":1217},"Run only ",{"type":40,"tag":62,"props":1219,"children":1220},{},[1221],{"type":46,"value":1222},"after",{"type":46,"value":1224}," Step 4 returned ",{"type":40,"tag":200,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":46,"value":1230},"$started = $true",{"type":46,"value":1232},". Write the per-user ",{"type":40,"tag":62,"props":1234,"children":1235},{},[1236],{"type":46,"value":1237},"marker file",{"type":46,"value":1239}," that Check B reads:",{"type":40,"tag":232,"props":1241,"children":1243},{"className":234,"code":1242,"language":236,"meta":237,"style":237},"$grantMarker = Join-Path $env:LOCALAPPDATA 'vcperf\\grant-verified'\nNew-Item -Path (Split-Path $grantMarker -Parent) -ItemType Directory -Force | Out-Null\n$payload = @{ grantedUtc = (Get-Date).ToUniversalTime().ToString('o'); vcperf = $vcperf } | ConvertTo-Json -Compress\n[IO.File]::WriteAllText(\"$grantMarker.tmp\", $payload, [Text.Encoding]::UTF8)\n\nMove-Item -LiteralPath \"$grantMarker.tmp\" -Destination $grantMarker -Force\n",[1244],{"type":40,"tag":200,"props":1245,"children":1246},{"__ignoreMap":237},[1247,1254,1262,1270,1278,1287],{"type":40,"tag":243,"props":1248,"children":1249},{"class":245,"line":246},[1250],{"type":40,"tag":243,"props":1251,"children":1252},{},[1253],{"type":46,"value":712},{"type":40,"tag":243,"props":1255,"children":1256},{"class":245,"line":255},[1257],{"type":40,"tag":243,"props":1258,"children":1259},{},[1260],{"type":46,"value":1261},"New-Item -Path (Split-Path $grantMarker -Parent) -ItemType Directory -Force | Out-Null\n",{"type":40,"tag":243,"props":1263,"children":1264},{"class":245,"line":660},[1265],{"type":40,"tag":243,"props":1266,"children":1267},{},[1268],{"type":46,"value":1269},"$payload = @{ grantedUtc = (Get-Date).ToUniversalTime().ToString('o'); vcperf = $vcperf } | ConvertTo-Json -Compress\n",{"type":40,"tag":243,"props":1271,"children":1272},{"class":245,"line":844},[1273],{"type":40,"tag":243,"props":1274,"children":1275},{},[1276],{"type":46,"value":1277},"[IO.File]::WriteAllText(\"$grantMarker.tmp\", $payload, [Text.Encoding]::UTF8)\n",{"type":40,"tag":243,"props":1279,"children":1280},{"class":245,"line":853},[1281],{"type":40,"tag":243,"props":1282,"children":1284},{"emptyLinePlaceholder":1283},true,[1285],{"type":46,"value":1286},"\n",{"type":40,"tag":243,"props":1288,"children":1289},{"class":245,"line":862},[1290],{"type":40,"tag":243,"props":1291,"children":1292},{},[1293],{"type":46,"value":1294},"Move-Item -LiteralPath \"$grantMarker.tmp\" -Destination $grantMarker -Force\n",{"type":40,"tag":518,"props":1296,"children":1297},{},[1298,1303],{"type":40,"tag":91,"props":1299,"children":1300},{},[1301],{"type":46,"value":1302},"Check presence of marker file to determine if grant is persisted.",{"type":40,"tag":91,"props":1304,"children":1305},{},[1306,1308,1313],{"type":46,"value":1307},"On every subsequent session, Check B returns ",{"type":40,"tag":200,"props":1309,"children":1311},{"className":1310},[],[1312],{"type":46,"value":685},{"type":46,"value":1314}," and the agent skips straight to Step 5.",{"type":40,"tag":70,"props":1316,"children":1318},{"id":1317},"step-5-invoke-vcperf-with-the-right-flag",[1319],{"type":46,"value":1320},"Step 5 — Invoke vcperf with the right flag",{"type":40,"tag":56,"props":1322,"children":1323},{},[1324],{"type":46,"value":1325},"When starting the tracing session:",{"type":40,"tag":518,"props":1327,"children":1328},{},[1329,1354],{"type":40,"tag":91,"props":1330,"children":1331},{},[1332,1337,1339,1345,1347,1352],{"type":40,"tag":62,"props":1333,"children":1334},{},[1335],{"type":46,"value":1336},"always",{"type":46,"value":1338}," pass ",{"type":40,"tag":200,"props":1340,"children":1342},{"className":1341},[],[1343],{"type":46,"value":1344},"\u002Fnoadmin",{"type":46,"value":1346}," to ",{"type":40,"tag":200,"props":1348,"children":1350},{"className":1349},[],[1351],{"type":46,"value":507},{"type":46,"value":1353},", or the start will fail with a privilege error.",{"type":40,"tag":91,"props":1355,"children":1356},{},[1357,1362,1364,1369,1371,1376,1378,1383],{"type":40,"tag":62,"props":1358,"children":1359},{},[1360],{"type":46,"value":1361},"Stale-grant recovery.",{"type":46,"value":1363}," If ",{"type":40,"tag":200,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":46,"value":554},{"type":46,"value":1370}," fails with a privilege error while Check B was ",{"type":40,"tag":200,"props":1372,"children":1374},{"className":1373},[],[1375],{"type":46,"value":685},{"type":46,"value":1377},", the cached grant is stale (the underlying ETW grant was revoked outside the agent). Recover by running Steps 2–4 directly — ",{"type":40,"tag":62,"props":1379,"children":1380},{},[1381],{"type":46,"value":1382},"skip Step 1",{"type":46,"value":151},{"type":40,"tag":49,"props":1385,"children":1387},{"id":1386},"core-workflow",[1388],{"type":46,"value":118},{"type":40,"tag":56,"props":1390,"children":1391},{},[1392,1394,1399,1401,1406,1408,1413,1414,1419],{"type":46,"value":1393},"There are three phases: ",{"type":40,"tag":62,"props":1395,"children":1396},{},[1397],{"type":46,"value":1398},"start",{"type":46,"value":1400}," a trace, ",{"type":40,"tag":62,"props":1402,"children":1403},{},[1404],{"type":46,"value":1405},"build",{"type":46,"value":1407}," your project, then ",{"type":40,"tag":62,"props":1409,"children":1410},{},[1411],{"type":46,"value":1412},"stop",{"type":46,"value":476},{"type":40,"tag":62,"props":1415,"children":1416},{},[1417],{"type":46,"value":1418},"analyze",{"type":46,"value":1420}," to produce results.",{"type":40,"tag":1422,"props":1423,"children":1424},"blockquote",{},[1425],{"type":40,"tag":56,"props":1426,"children":1427},{},[1428,1430,1435,1437,1442,1444,1449,1451,1457,1459,1464,1466,1471,1473,1478],{"type":46,"value":1429},"Below, ",{"type":40,"tag":200,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":46,"value":304},{"type":46,"value":1436}," is shorthand for the resolved ",{"type":40,"tag":200,"props":1438,"children":1440},{"className":1439},[],[1441],{"type":46,"value":277},{"type":46,"value":1443}," absolute path run directly in PowerShell (",{"type":40,"tag":200,"props":1445,"children":1447},{"className":1446},[],[1448],{"type":46,"value":319},{"type":46,"value":1450},"), per the ",{"type":40,"tag":95,"props":1452,"children":1454},{"href":1453},"#invocation-rule-read-before-running-any-vcperf-command",[1455],{"type":46,"value":1456},"Invocation rule",{"type":46,"value":1458},". Never run a bare ",{"type":40,"tag":200,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":46,"value":304},{"type":46,"value":1465}," (it hits the VS-bundled copy on ",{"type":40,"tag":200,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":46,"value":360},{"type":46,"value":1472},"), and judge success by the output file rather than ",{"type":40,"tag":200,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":46,"value":390},{"type":46,"value":151},{"type":40,"tag":70,"props":1480,"children":1482},{"id":1481},"_1-start-a-tracing-session",[1483],{"type":46,"value":1484},"1. Start a tracing session",{"type":40,"tag":232,"props":1486,"children":1489},{"className":1487,"code":1488,"language":46},[774],"vcperf \u002Fstart [\u002Fnoadmin] [\u002Fnocpusampling] [\u002Flevel1 | \u002Flevel2 | \u002Flevel3] \u003CsessionName>\n",[1490],{"type":40,"tag":200,"props":1491,"children":1492},{"__ignoreMap":237},[1493],{"type":46,"value":1488},{"type":40,"tag":1495,"props":1496,"children":1497},"table",{},[1498,1517],{"type":40,"tag":1499,"props":1500,"children":1501},"thead",{},[1502],{"type":40,"tag":1503,"props":1504,"children":1505},"tr",{},[1506,1512],{"type":40,"tag":1507,"props":1508,"children":1509},"th",{},[1510],{"type":46,"value":1511},"Flag",{"type":40,"tag":1507,"props":1513,"children":1514},{},[1515],{"type":46,"value":1516},"Purpose",{"type":40,"tag":1518,"props":1519,"children":1520},"tbody",{},[1521,1538,1555,1572,1589],{"type":40,"tag":1503,"props":1522,"children":1523},{},[1524,1533],{"type":40,"tag":1525,"props":1526,"children":1527},"td",{},[1528],{"type":40,"tag":200,"props":1529,"children":1531},{"className":1530},[],[1532],{"type":46,"value":1344},{"type":40,"tag":1525,"props":1534,"children":1535},{},[1536],{"type":46,"value":1537},"Run without admin (less data)",{"type":40,"tag":1503,"props":1539,"children":1540},{},[1541,1550],{"type":40,"tag":1525,"props":1542,"children":1543},{},[1544],{"type":40,"tag":200,"props":1545,"children":1547},{"className":1546},[],[1548],{"type":46,"value":1549},"\u002Fnocpusampling",{"type":40,"tag":1525,"props":1551,"children":1552},{},[1553],{"type":46,"value":1554},"Skip CPU sampling",{"type":40,"tag":1503,"props":1556,"children":1557},{},[1558,1567],{"type":40,"tag":1525,"props":1559,"children":1560},{},[1561],{"type":40,"tag":200,"props":1562,"children":1564},{"className":1563},[],[1565],{"type":46,"value":1566},"\u002Flevel1",{"type":40,"tag":1525,"props":1568,"children":1569},{},[1570],{"type":46,"value":1571},"Basic events",{"type":40,"tag":1503,"props":1573,"children":1574},{},[1575,1584],{"type":40,"tag":1525,"props":1576,"children":1577},{},[1578],{"type":40,"tag":200,"props":1579,"children":1581},{"className":1580},[],[1582],{"type":46,"value":1583},"\u002Flevel2",{"type":40,"tag":1525,"props":1585,"children":1586},{},[1587],{"type":46,"value":1588},"Adds additional detail",{"type":40,"tag":1503,"props":1590,"children":1591},{},[1592,1601],{"type":40,"tag":1525,"props":1593,"children":1594},{},[1595],{"type":40,"tag":200,"props":1596,"children":1598},{"className":1597},[],[1599],{"type":46,"value":1600},"\u002Flevel3",{"type":40,"tag":1525,"props":1602,"children":1603},{},[1604],{"type":46,"value":1605},"Maximum detail, includes template instantiation data",{"type":40,"tag":56,"props":1607,"children":1608},{},[1609,1611,1616],{"type":46,"value":1610},"Use ",{"type":40,"tag":200,"props":1612,"children":1614},{"className":1613},[],[1615],{"type":46,"value":1600},{"type":46,"value":1617}," when you plan to analyze templates.",{"type":40,"tag":70,"props":1619,"children":1621},{"id":1620},"_2-build-your-project",[1622],{"type":46,"value":1623},"2. Build your project",{"type":40,"tag":56,"props":1625,"children":1626},{},[1627,1629,1635,1637,1643,1645,1650],{"type":46,"value":1628},"Run your normal build command while the trace is active. Any MSVC-driven build works — MSBuild, CMake (Ninja or MSBuild generator), or direct ",{"type":40,"tag":200,"props":1630,"children":1632},{"className":1631},[],[1633],{"type":46,"value":1634},"cl.exe",{"type":46,"value":1636},". The ",{"type":40,"tag":1638,"props":1639,"children":1640},"em",{},[1641],{"type":46,"value":1642},"compiler",{"type":46,"value":1644}," must be MSVC; the ",{"type":40,"tag":1638,"props":1646,"children":1647},{},[1648],{"type":46,"value":1649},"build driver",{"type":46,"value":1651}," is your choice.",{"type":40,"tag":56,"props":1653,"children":1654},{},[1655,1657,1663,1664,1670],{"type":46,"value":1656},"When building solution files, look for either ",{"type":40,"tag":200,"props":1658,"children":1660},{"className":1659},[],[1661],{"type":46,"value":1662},".sln",{"type":46,"value":432},{"type":40,"tag":200,"props":1665,"children":1667},{"className":1666},[],[1668],{"type":46,"value":1669},".slnx",{"type":46,"value":151},{"type":40,"tag":1672,"props":1673,"children":1675},"h4",{"id":1674},"build-configuration-matters-debug-vs-release",[1676],{"type":46,"value":1677},"Build configuration matters (Debug vs Release)",{"type":40,"tag":56,"props":1679,"children":1680},{},[1681,1683,1688,1690,1696,1698,1704,1706,1712],{"type":46,"value":1682},"vcperf only reports work the compiler actually performs. ",{"type":40,"tag":62,"props":1684,"children":1685},{},[1686],{"type":46,"value":1687},"Debug",{"type":46,"value":1689}," builds skip most optimizer passes, so the ",{"type":40,"tag":200,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":46,"value":1695},"Functions",{"type":46,"value":1697}," section of the JSON output will be sparse or empty — you will not see backend codegen, inlining, or optimization hotspots. Frontend phases (",{"type":40,"tag":200,"props":1699,"children":1701},{"className":1700},[],[1702],{"type":46,"value":1703},"IncludedFiles",{"type":46,"value":1705},", ",{"type":40,"tag":200,"props":1707,"children":1709},{"className":1708},[],[1710],{"type":46,"value":1711},"Templates",{"type":46,"value":1713},") are still captured normally because parsing and template instantiation happen regardless of configuration.",{"type":40,"tag":56,"props":1715,"children":1716},{},[1717,1719,1724,1726,1732,1734,1739],{"type":46,"value":1718},"For meaningful function-level analysis, build in ",{"type":40,"tag":62,"props":1720,"children":1721},{},[1722],{"type":46,"value":1723},"Release",{"type":46,"value":1725}," (or another optimized configuration such as ",{"type":40,"tag":200,"props":1727,"children":1729},{"className":1728},[],[1730],{"type":46,"value":1731},"RelWithDebInfo",{"type":46,"value":1733},"). As a rule, profile the configuration you intend to ship; before choosing Debug, confirm with the user that frontend-only data is enough for their question, and call out the missing ",{"type":40,"tag":200,"props":1735,"children":1737},{"className":1736},[],[1738],{"type":46,"value":1695},{"type":46,"value":1740}," data in your report.",{"type":40,"tag":70,"props":1742,"children":1744},{"id":1743},"_3-stop-and-analyze",[1745],{"type":46,"value":1746},"3. Stop and analyze",{"type":40,"tag":232,"props":1748,"children":1751},{"className":1749,"code":1750,"language":46},[774],"vcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> output.etl\nvcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> output.etl \u002FjsonAnalysis output.json\nvcperf \u002Fstop [\u002Ftemplates] \u003CsessionName> \u002Ftimetrace output.json\n",[1752],{"type":40,"tag":200,"props":1753,"children":1754},{"__ignoreMap":237},[1755],{"type":46,"value":1750},{"type":40,"tag":56,"props":1757,"children":1758},{},[1759],{"type":46,"value":1760},"Or capture raw first, then analyze offline:",{"type":40,"tag":232,"props":1762,"children":1765},{"className":1763,"code":1764,"language":46},[774],"vcperf \u002Fstopnoanalyze \u003CsessionName> raw.etl\nvcperf \u002Fanalyze [\u002Ftemplates] raw.etl output.etl \u002FjsonAnalysis output.json\n",[1766],{"type":40,"tag":200,"props":1767,"children":1768},{"__ignoreMap":237},[1769],{"type":46,"value":1764},{"type":40,"tag":70,"props":1771,"children":1773},{"id":1772},"_4-avoid-timing-gaps-run-startbuildstop-as-one-shell-command",[1774],{"type":46,"value":1775},"4. Avoid timing gaps — run start\u002Fbuild\u002Fstop as one shell command",{"type":40,"tag":56,"props":1777,"children":1778},{},[1779,1784,1786,1791,1793,1798,1800,1819,1821,1827],{"type":40,"tag":200,"props":1780,"children":1782},{"className":1781},[],[1783],{"type":46,"value":304},{"type":46,"value":1785}," records ETW events from ",{"type":40,"tag":200,"props":1787,"children":1789},{"className":1788},[],[1790],{"type":46,"value":608},{"type":46,"value":1792}," until ",{"type":40,"tag":200,"props":1794,"children":1796},{"className":1795},[],[1797],{"type":46,"value":430},{"type":46,"value":1799},". ",{"type":40,"tag":62,"props":1801,"children":1802},{},[1803,1805,1810,1812,1817],{"type":46,"value":1804},"Any wall-clock gap between ",{"type":40,"tag":200,"props":1806,"children":1808},{"className":1807},[],[1809],{"type":46,"value":608},{"type":46,"value":1811},", the build, and ",{"type":40,"tag":200,"props":1813,"children":1815},{"className":1814},[],[1816],{"type":46,"value":430},{"type":46,"value":1818}," is captured as noise",{"type":46,"value":1820}," — model thinking, tool-call round-trips, prompts, and shell startup all inflate ",{"type":40,"tag":200,"props":1822,"children":1824},{"className":1823},[],[1825],{"type":46,"value":1826},"BuildDurationMs",{"type":46,"value":1828}," and can shift hotspot rankings.",{"type":40,"tag":56,"props":1830,"children":1831},{},[1832,1834,1847],{"type":46,"value":1833},"From a CLI agent or any interactive workflow, ",{"type":40,"tag":62,"props":1835,"children":1836},{},[1837,1839,1845],{"type":46,"value":1838},"chain ",{"type":40,"tag":200,"props":1840,"children":1842},{"className":1841},[],[1843],{"type":46,"value":1844},"\u002Fstart → build → \u002Fstop",{"type":46,"value":1846}," into a single shell command",{"type":46,"value":1848},". Do not issue them as three separate tool calls — the latency between calls (often several seconds each) contaminates the trace.",{"type":40,"tag":56,"props":1850,"children":1851},{},[1852],{"type":40,"tag":62,"props":1853,"children":1854},{},[1855],{"type":46,"value":1856},"PowerShell with MSBuild (single invocation — recommended):",{"type":40,"tag":232,"props":1858,"children":1860},{"className":234,"code":1859,"language":236,"meta":237,"style":237},"# $vcperf holds the absolute path resolved earlier. Run as one scriptblock so\n# \u002Fstart -> build -> \u002Fstop execute back-to-back with no timing gaps. Judge trace\n# success by the output files (Test-Path), not $LASTEXITCODE (see Invocation rule).\n\n$buildExit = & {\n    & $vcperf \u002Fstart \u002Fnoadmin \u002Flevel3 MySession | Out-Host\n    msbuild Project.sln \u002Fm \u002Ft:Rebuild \u002Fp:Configuration=Release | Out-Host\n    $exitCode = $LASTEXITCODE\n    & $vcperf \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json | Out-Host\n    $exitCode\n}\n$traceOk = (Test-Path out.etl) -and (Test-Path out.json)\n",[1861],{"type":40,"tag":200,"props":1862,"children":1863},{"__ignoreMap":237},[1864,1872,1880,1888,1895,1903,1911,1919,1927,1935,1943,1950],{"type":40,"tag":243,"props":1865,"children":1866},{"class":245,"line":246},[1867],{"type":40,"tag":243,"props":1868,"children":1869},{},[1870],{"type":46,"value":1871},"# $vcperf holds the absolute path resolved earlier. Run as one scriptblock so\n",{"type":40,"tag":243,"props":1873,"children":1874},{"class":245,"line":255},[1875],{"type":40,"tag":243,"props":1876,"children":1877},{},[1878],{"type":46,"value":1879},"# \u002Fstart -> build -> \u002Fstop execute back-to-back with no timing gaps. Judge trace\n",{"type":40,"tag":243,"props":1881,"children":1882},{"class":245,"line":660},[1883],{"type":40,"tag":243,"props":1884,"children":1885},{},[1886],{"type":46,"value":1887},"# success by the output files (Test-Path), not $LASTEXITCODE (see Invocation rule).\n",{"type":40,"tag":243,"props":1889,"children":1890},{"class":245,"line":844},[1891],{"type":40,"tag":243,"props":1892,"children":1893},{"emptyLinePlaceholder":1283},[1894],{"type":46,"value":1286},{"type":40,"tag":243,"props":1896,"children":1897},{"class":245,"line":853},[1898],{"type":40,"tag":243,"props":1899,"children":1900},{},[1901],{"type":46,"value":1902},"$buildExit = & {\n",{"type":40,"tag":243,"props":1904,"children":1905},{"class":245,"line":862},[1906],{"type":40,"tag":243,"props":1907,"children":1908},{},[1909],{"type":46,"value":1910},"    & $vcperf \u002Fstart \u002Fnoadmin \u002Flevel3 MySession | Out-Host\n",{"type":40,"tag":243,"props":1912,"children":1913},{"class":245,"line":871},[1914],{"type":40,"tag":243,"props":1915,"children":1916},{},[1917],{"type":46,"value":1918},"    msbuild Project.sln \u002Fm \u002Ft:Rebuild \u002Fp:Configuration=Release | Out-Host\n",{"type":40,"tag":243,"props":1920,"children":1921},{"class":245,"line":880},[1922],{"type":40,"tag":243,"props":1923,"children":1924},{},[1925],{"type":46,"value":1926},"    $exitCode = $LASTEXITCODE\n",{"type":40,"tag":243,"props":1928,"children":1929},{"class":245,"line":889},[1930],{"type":40,"tag":243,"props":1931,"children":1932},{},[1933],{"type":46,"value":1934},"    & $vcperf \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json | Out-Host\n",{"type":40,"tag":243,"props":1936,"children":1937},{"class":245,"line":898},[1938],{"type":40,"tag":243,"props":1939,"children":1940},{},[1941],{"type":46,"value":1942},"    $exitCode\n",{"type":40,"tag":243,"props":1944,"children":1945},{"class":245,"line":907},[1946],{"type":40,"tag":243,"props":1947,"children":1948},{},[1949],{"type":46,"value":958},{"type":40,"tag":243,"props":1951,"children":1952},{"class":245,"line":916},[1953],{"type":40,"tag":243,"props":1954,"children":1955},{},[1956],{"type":46,"value":1957},"$traceOk = (Test-Path out.etl) -and (Test-Path out.json)\n",{"type":40,"tag":56,"props":1959,"children":1960},{},[1961],{"type":40,"tag":62,"props":1962,"children":1963},{},[1964],{"type":46,"value":1965},"PowerShell with CMake (single invocation):",{"type":40,"tag":232,"props":1967,"children":1969},{"className":234,"code":1968,"language":236,"meta":237,"style":237},"$buildExit = & {\n    & $vcperf \u002Fstart \u002Fnoadmin \u002Flevel3 MySession | Out-Host\n    cmake --build build --target clean | Out-Host\n    cmake --build build --parallel | Out-Host\n    $exitCode = $LASTEXITCODE\n    & $vcperf \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json | Out-Host\n    $exitCode\n}\n$traceOk = (Test-Path out.etl) -and (Test-Path out.json)\n",[1970],{"type":40,"tag":200,"props":1971,"children":1972},{"__ignoreMap":237},[1973,1980,1987,1995,2003,2010,2017,2024,2031],{"type":40,"tag":243,"props":1974,"children":1975},{"class":245,"line":246},[1976],{"type":40,"tag":243,"props":1977,"children":1978},{},[1979],{"type":46,"value":1902},{"type":40,"tag":243,"props":1981,"children":1982},{"class":245,"line":255},[1983],{"type":40,"tag":243,"props":1984,"children":1985},{},[1986],{"type":46,"value":1910},{"type":40,"tag":243,"props":1988,"children":1989},{"class":245,"line":660},[1990],{"type":40,"tag":243,"props":1991,"children":1992},{},[1993],{"type":46,"value":1994},"    cmake --build build --target clean | Out-Host\n",{"type":40,"tag":243,"props":1996,"children":1997},{"class":245,"line":844},[1998],{"type":40,"tag":243,"props":1999,"children":2000},{},[2001],{"type":46,"value":2002},"    cmake --build build --parallel | Out-Host\n",{"type":40,"tag":243,"props":2004,"children":2005},{"class":245,"line":853},[2006],{"type":40,"tag":243,"props":2007,"children":2008},{},[2009],{"type":46,"value":1926},{"type":40,"tag":243,"props":2011,"children":2012},{"class":245,"line":862},[2013],{"type":40,"tag":243,"props":2014,"children":2015},{},[2016],{"type":46,"value":1934},{"type":40,"tag":243,"props":2018,"children":2019},{"class":245,"line":871},[2020],{"type":40,"tag":243,"props":2021,"children":2022},{},[2023],{"type":46,"value":1942},{"type":40,"tag":243,"props":2025,"children":2026},{"class":245,"line":880},[2027],{"type":40,"tag":243,"props":2028,"children":2029},{},[2030],{"type":46,"value":958},{"type":40,"tag":243,"props":2032,"children":2033},{"class":245,"line":889},[2034],{"type":40,"tag":243,"props":2035,"children":2036},{},[2037],{"type":46,"value":1957},{"type":40,"tag":56,"props":2039,"children":2040},{},[2041,2047,2049,2055,2057,2063,2065,2070],{"type":40,"tag":200,"props":2042,"children":2044},{"className":2043},[],[2045],{"type":46,"value":2046},"$buildExit",{"type":46,"value":2048}," is the build tool's own exit code (reliable — an ordinary process), telling you whether the build succeeded. ",{"type":40,"tag":200,"props":2050,"children":2052},{"className":2051},[],[2053],{"type":46,"value":2054},"$traceOk",{"type":46,"value":2056}," confirms vcperf actually produced the trace. The ",{"type":40,"tag":200,"props":2058,"children":2060},{"className":2059},[],[2061],{"type":46,"value":2062},";",{"type":46,"value":2064}," sequence never short-circuits, so ",{"type":40,"tag":200,"props":2066,"children":2068},{"className":2067},[],[2069],{"type":46,"value":430},{"type":46,"value":2071}," always runs even if the build fails.",{"type":40,"tag":56,"props":2073,"children":2074},{},[2075,2080,2082,2088,2090,2096],{"type":40,"tag":62,"props":2076,"children":2077},{},[2078],{"type":46,"value":2079},"cmd.exe alternative",{"type":46,"value":2081}," (if you prefer ",{"type":40,"tag":200,"props":2083,"children":2085},{"className":2084},[],[2086],{"type":46,"value":2087},"&&",{"type":46,"value":2089}," short-circuit semantics; substitute the full path for ",{"type":40,"tag":200,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":46,"value":2095},"%VCPERF%",{"type":46,"value":2097},"):",{"type":40,"tag":232,"props":2099,"children":2103},{"className":2100,"code":2101,"language":2102,"meta":237,"style":237},"language-cmd shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\"%VCPERF%\" \u002Fstart \u002Fnoadmin \u002Flevel3 MySession && cmake --build build --target clean && cmake --build build --parallel && \"%VCPERF%\" \u002Fstop \u002Ftemplates MySession out.etl \u002FjsonAnalysis out.json\n","cmd",[2104],{"type":40,"tag":200,"props":2105,"children":2106},{"__ignoreMap":237},[2107],{"type":40,"tag":243,"props":2108,"children":2109},{"class":245,"line":246},[2110],{"type":40,"tag":243,"props":2111,"children":2112},{},[2113],{"type":46,"value":2101},{"type":40,"tag":56,"props":2115,"children":2116},{},[2117,2122,2124,2129,2131,2136,2138,2144,2145,2151],{"type":40,"tag":200,"props":2118,"children":2120},{"className":2119},[],[2121],{"type":46,"value":2087},{"type":46,"value":2123}," skips ",{"type":40,"tag":200,"props":2125,"children":2127},{"className":2126},[],[2128],{"type":46,"value":430},{"type":46,"value":2130}," if the build fails; replace the ",{"type":40,"tag":200,"props":2132,"children":2134},{"className":2133},[],[2135],{"type":46,"value":2087},{"type":46,"value":2137}," before the final ",{"type":40,"tag":200,"props":2139,"children":2141},{"className":2140},[],[2142],{"type":46,"value":2143},"\"%VCPERF%\" \u002Fstop",{"type":46,"value":991},{"type":40,"tag":200,"props":2146,"children":2148},{"className":2147},[],[2149],{"type":46,"value":2150},"&",{"type":46,"value":2152}," to emit the trace anyway.",{"type":40,"tag":56,"props":2154,"children":2155},{},[2156,2158,2162,2164,2169],{"type":46,"value":2157},"The same rule applies to incremental measurements (see ",{"type":40,"tag":95,"props":2159,"children":2160},{"href":183},[2161],{"type":46,"value":186},{"type":46,"value":2163},"): the touch step may be a separate command, but ",{"type":40,"tag":200,"props":2165,"children":2167},{"className":2166},[],[2168],{"type":46,"value":1844},{"type":46,"value":2170}," must be one chained invocation.",{"type":40,"tag":49,"props":2172,"children":2174},{"id":2173},"the-jsonanalysis-flag",[2175],{"type":46,"value":126},{"type":40,"tag":56,"props":2177,"children":2178},{},[2179],{"type":46,"value":2180},"Produces a structured JSON report alongside the ETL output.",{"type":40,"tag":56,"props":2182,"children":2183},{},[2184,2189,2191,2197,2199,2203],{"type":40,"tag":62,"props":2185,"children":2186},{},[2187],{"type":46,"value":2188},"Syntax:",{"type":46,"value":2190}," ",{"type":40,"tag":200,"props":2192,"children":2194},{"className":2193},[],[2195],{"type":46,"value":2196},"\u002FjsonAnalysis \u003Cpath>.json",{"type":46,"value":2198}," — must appear ",{"type":40,"tag":62,"props":2200,"children":2201},{},[2202],{"type":46,"value":1222},{"type":46,"value":2204}," the ETL output path.",{"type":40,"tag":56,"props":2206,"children":2207},{},[2208],{"type":40,"tag":62,"props":2209,"children":2210},{},[2211],{"type":46,"value":2212},"Constraints:",{"type":40,"tag":518,"props":2214,"children":2215},{},[2216,2229],{"type":40,"tag":91,"props":2217,"children":2218},{},[2219,2221,2227],{"type":46,"value":2220},"Cannot be combined with ",{"type":40,"tag":200,"props":2222,"children":2224},{"className":2223},[],[2225],{"type":46,"value":2226},"\u002Ftimetrace",{"type":46,"value":2228}," (mutually exclusive).",{"type":40,"tag":91,"props":2230,"children":2231},{},[2232,2234,2240],{"type":46,"value":2233},"Pair with ",{"type":40,"tag":200,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":46,"value":2239},"\u002Ftemplates",{"type":46,"value":2241}," to include template data.",{"type":40,"tag":56,"props":2243,"children":2244},{},[2245],{"type":40,"tag":62,"props":2246,"children":2247},{},[2248],{"type":46,"value":2249},"Example:",{"type":40,"tag":232,"props":2251,"children":2254},{"className":2252,"code":2253,"language":46},[774],"vcperf \u002Fstop \u002Ftemplates MyBuild output.etl \u002FjsonAnalysis analysis.json\n",[2255],{"type":40,"tag":200,"props":2256,"children":2257},{"__ignoreMap":237},[2258],{"type":46,"value":2253},{"type":40,"tag":49,"props":2260,"children":2262},{"id":2261},"json-output-schema",[2263],{"type":46,"value":2264},"JSON Output Schema",{"type":40,"tag":56,"props":2266,"children":2267},{},[2268,2270,2275,2277,2282,2283,2288,2289,2294,2296,2302],{"type":46,"value":2269},"See ",{"type":40,"tag":95,"props":2271,"children":2273},{"href":2272},"references\u002Fjson-schema.md",[2274],{"type":46,"value":2272},{"type":46,"value":2276}," for the full field-by-field schema of the JSON analysis output, including ",{"type":40,"tag":200,"props":2278,"children":2280},{"className":2279},[],[2281],{"type":46,"value":1703},{"type":46,"value":1705},{"type":40,"tag":200,"props":2284,"children":2286},{"className":2285},[],[2287],{"type":46,"value":1695},{"type":46,"value":1705},{"type":40,"tag":200,"props":2290,"children":2292},{"className":2291},[],[2293],{"type":46,"value":1711},{"type":46,"value":2295},", and ",{"type":40,"tag":200,"props":2297,"children":2299},{"className":2298},[],[2300],{"type":46,"value":2301},"IncludeTree",{"type":46,"value":2303}," sections.",{"type":40,"tag":2305,"props":2306,"children":2307},"hr",{},[],{"type":40,"tag":49,"props":2309,"children":2311},{"id":2310},"baseline-measurement",[2312],{"type":46,"value":135},{"type":40,"tag":56,"props":2314,"children":2315},{},[2316,2318,2322],{"type":46,"value":2317},"Establish a baseline ",{"type":40,"tag":62,"props":2319,"children":2320},{},[2321],{"type":46,"value":107},{"type":46,"value":2323}," applying the candidate change. A single build measurement is noisy — file system caches, antivirus, background processes, and thermal throttling all introduce variance, so always run a 5-build sample.",{"type":40,"tag":56,"props":2325,"children":2326},{},[2327,2332,2334,2339,2341,2345],{"type":40,"tag":62,"props":2328,"children":2329},{},[2330],{"type":46,"value":2331},"Do not run vcperf during these builds.",{"type":46,"value":2333}," The diagnostic trace that tells you ",{"type":40,"tag":1638,"props":2335,"children":2336},{},[2337],{"type":46,"value":2338},"what",{"type":46,"value":2340}," to change is captured separately via the ",{"type":40,"tag":95,"props":2342,"children":2343},{"href":115},[2344],{"type":46,"value":118},{"type":46,"value":2346},"; baseline and post-change timing builds are plain, uninstrumented wall-clock builds. vcperf's ETW instrumentation adds overhead that would contaminate timing comparisons.",{"type":40,"tag":56,"props":2348,"children":2349},{},[2350,2355],{"type":40,"tag":62,"props":2351,"children":2352},{},[2353],{"type":46,"value":2354},"Make no changes to the project while measuring the baseline.",{"type":46,"value":2356}," No modifications to the project until all baseline builds complete.",{"type":40,"tag":70,"props":2358,"children":2360},{"id":2359},"procedure",[2361],{"type":46,"value":2362},"Procedure",{"type":40,"tag":87,"props":2364,"children":2365},{},[2366,2407,2417,2422,2468],{"type":40,"tag":91,"props":2367,"children":2368},{},[2369,2374,2376,2381,2383,2389,2391,2397,2399,2405],{"type":40,"tag":62,"props":2370,"children":2371},{},[2372],{"type":46,"value":2373},"Run 5 builds",{"type":46,"value":2375}," of the target as a full clean rebuild (clean before every build), ",{"type":40,"tag":62,"props":2377,"children":2378},{},[2379],{"type":46,"value":2380},"without vcperf",{"type":46,"value":2382},". Every run uses identical configuration, platform, build parallelism (e.g. MSBuild ",{"type":40,"tag":200,"props":2384,"children":2386},{"className":2385},[],[2387],{"type":46,"value":2388},"\u002Fm",{"type":46,"value":2390},", CMake ",{"type":40,"tag":200,"props":2392,"children":2394},{"className":2393},[],[2395],{"type":46,"value":2396},"--parallel",{"type":46,"value":2398},", ninja's default ",{"type":40,"tag":200,"props":2400,"children":2402},{"className":2401},[],[2403],{"type":46,"value":2404},"-j",{"type":46,"value":2406},"), and machine state (plugged in, no background load).",{"type":40,"tag":91,"props":2408,"children":2409},{},[2410,2415],{"type":40,"tag":62,"props":2411,"children":2412},{},[2413],{"type":46,"value":2414},"Average the 5 builds",{"type":46,"value":2416}," for a stable baseline.",{"type":40,"tag":91,"props":2418,"children":2419},{},[2420],{"type":46,"value":2421},"Record the baseline average and standard deviation. Compare post-change measurements against this baseline using the same methodology (5 uninstrumented builds).",{"type":40,"tag":91,"props":2423,"children":2424},{},[2425,2430,2432,2438,2439,2445,2447,2452,2454,2459,2461,2466],{"type":40,"tag":62,"props":2426,"children":2427},{},[2428],{"type":46,"value":2429},"Measure wall-clock time",{"type":46,"value":2431}," of each build (e.g. ",{"type":40,"tag":200,"props":2433,"children":2435},{"className":2434},[],[2436],{"type":46,"value":2437},"Measure-Command { msbuild ... }",{"type":46,"value":432},{"type":40,"tag":200,"props":2440,"children":2442},{"className":2441},[],[2443],{"type":46,"value":2444},"Measure-Command { cmake --build build }",{"type":46,"value":2446},", or the build driver's own elapsed time). Record in ",{"type":40,"tag":62,"props":2448,"children":2449},{},[2450],{"type":46,"value":2451},"seconds",{"type":46,"value":2453}," — all measurements, deltas, and statistics in this skill are in seconds, never milliseconds. Do ",{"type":40,"tag":62,"props":2455,"children":2456},{},[2457],{"type":46,"value":2458},"not",{"type":46,"value":2460}," use ",{"type":40,"tag":200,"props":2462,"children":2464},{"className":2463},[],[2465],{"type":46,"value":1826},{"type":46,"value":2467}," from a vcperf JSON; that field comes from an instrumented trace and is not the metric you are optimizing.",{"type":40,"tag":91,"props":2469,"children":2470},{},[2471,2476],{"type":40,"tag":62,"props":2472,"children":2473},{},[2474],{"type":46,"value":2475},"Keep fixed between runs:",{"type":46,"value":2477}," build parallelism, build-server \u002F node reuse, configuration, platform, power state, source\u002Foutput state. Do not change any source files or project settings during baseline measurement.",{"type":40,"tag":49,"props":2479,"children":2481},{"id":2480},"iterative-build-measurement",[2482],{"type":46,"value":186},{"type":40,"tag":56,"props":2484,"children":2485},{},[2486,2488,2493],{"type":46,"value":2487},"Use this only ",{"type":40,"tag":62,"props":2489,"children":2490},{},[2491],{"type":46,"value":2492},"after one full rebuild",{"type":46,"value":151},{"type":40,"tag":70,"props":2495,"children":2497},{"id":2496},"procedure-overview",[2498],{"type":46,"value":2499},"Procedure overview",{"type":40,"tag":56,"props":2501,"children":2502},{},[2503,2505,2510],{"type":46,"value":2504},"An ",{"type":40,"tag":62,"props":2506,"children":2507},{},[2508],{"type":46,"value":2509},"A\u002FB comparison of two incremental builds",{"type":46,"value":2511}," with an identical workload:",{"type":40,"tag":518,"props":2513,"children":2514},{},[2515,2525],{"type":40,"tag":91,"props":2516,"children":2517},{},[2518,2523],{"type":40,"tag":62,"props":2519,"children":2520},{},[2521],{"type":46,"value":2522},"A:",{"type":46,"value":2524}," candidate changes applied, the same set of TUs forced dirty",{"type":40,"tag":91,"props":2526,"children":2527},{},[2528,2533],{"type":40,"tag":62,"props":2529,"children":2530},{},[2531],{"type":46,"value":2532},"B:",{"type":46,"value":2534}," candidate changes reverted, the same set of TUs forced dirty",{"type":40,"tag":56,"props":2536,"children":2537},{},[2538,2540,2546],{"type":46,"value":2539},"Both runs must mark the same files dirty and start from a ",{"type":40,"tag":200,"props":2541,"children":2543},{"className":2542},[],[2544],{"type":46,"value":2545},".obj",{"type":46,"value":2547}," state matching the source they are about to compile.",{"type":40,"tag":70,"props":2549,"children":2551},{"id":2550},"step-1-pick-the-tu-files-to-touch",[2552],{"type":46,"value":2553},"Step 1 — Pick the TU files to touch",{"type":40,"tag":56,"props":2555,"children":2556},{},[2557,2559,2564],{"type":46,"value":2558},"Combine two signals and ",{"type":40,"tag":62,"props":2560,"children":2561},{},[2562],{"type":46,"value":2563},"prefer their intersection",{"type":46,"value":2565}," (fall back to whichever is non-empty):",{"type":40,"tag":56,"props":2567,"children":2568},{},[2569,2571,2576,2578,2582,2584,2589,2591],{"type":46,"value":2570},"Reuse the ",{"type":40,"tag":200,"props":2572,"children":2574},{"className":2573},[],[2575],{"type":46,"value":368},{"type":46,"value":2577}," output from ",{"type":40,"tag":95,"props":2579,"children":2580},{"href":115},[2581],{"type":46,"value":118},{"type":46,"value":2583},". After applying ",{"type":40,"tag":95,"props":2585,"children":2586},{"href":157},[2587],{"type":46,"value":2588},"the selection rules",{"type":46,"value":2590},", take the top expensive headers in ",{"type":40,"tag":200,"props":2592,"children":2594},{"className":2593},[],[2595],{"type":46,"value":1703},{"type":40,"tag":518,"props":2597,"children":2598},{},[2599],{"type":40,"tag":91,"props":2600,"children":2601},{},[2602,2607,2609,2614,2616],{"type":40,"tag":62,"props":2603,"children":2604},{},[2605],{"type":46,"value":2606},"Frequently-changed TUs from git churn.",{"type":46,"value":2608}," Use only commits ",{"type":40,"tag":62,"props":2610,"children":2611},{},[2612],{"type":46,"value":2613},"before the branch fork-point",{"type":46,"value":2615}," (see \"Git History Rules\" below):\n",{"type":40,"tag":232,"props":2617,"children":2619},{"className":234,"code":2618,"language":236,"meta":237,"style":237},"$forkPoint = git merge-base HEAD origin\u002Fmain\ngit log --name-only --pretty=format: $forkPoint -- '*.cpp' '*.cxx' '*.cc' '*.c' |\n    Where-Object { $_ } |\n    Group-Object | Sort-Object Count -Descending |\n    Select-Object -First 50\n",[2620],{"type":40,"tag":200,"props":2621,"children":2622},{"__ignoreMap":237},[2623,2631,2639,2647,2655],{"type":40,"tag":243,"props":2624,"children":2625},{"class":245,"line":246},[2626],{"type":40,"tag":243,"props":2627,"children":2628},{},[2629],{"type":46,"value":2630},"$forkPoint = git merge-base HEAD origin\u002Fmain\n",{"type":40,"tag":243,"props":2632,"children":2633},{"class":245,"line":255},[2634],{"type":40,"tag":243,"props":2635,"children":2636},{},[2637],{"type":46,"value":2638},"git log --name-only --pretty=format: $forkPoint -- '*.cpp' '*.cxx' '*.cc' '*.c' |\n",{"type":40,"tag":243,"props":2640,"children":2641},{"class":245,"line":660},[2642],{"type":40,"tag":243,"props":2643,"children":2644},{},[2645],{"type":46,"value":2646},"    Where-Object { $_ } |\n",{"type":40,"tag":243,"props":2648,"children":2649},{"class":245,"line":844},[2650],{"type":40,"tag":243,"props":2651,"children":2652},{},[2653],{"type":46,"value":2654},"    Group-Object | Sort-Object Count -Descending |\n",{"type":40,"tag":243,"props":2656,"children":2657},{"class":245,"line":853},[2658],{"type":40,"tag":243,"props":2659,"children":2660},{},[2661],{"type":46,"value":2662},"    Select-Object -First 50\n",{"type":40,"tag":70,"props":2664,"children":2666},{"id":2665},"step-2-touch-do-not-edit-the-chosen-files",[2667],{"type":46,"value":2668},"Step 2 — Touch (do not edit) the chosen files",{"type":40,"tag":56,"props":2670,"children":2671},{},[2672],{"type":46,"value":2673},"Update last-write-time only:",{"type":40,"tag":232,"props":2675,"children":2677},{"className":234,"code":2676,"language":236,"meta":237,"style":237},"$touchTime = (Get-Date).ToUniversalTime()\nforeach ($file in $tuFiles) {\n    if (Test-Path $file) { (Get-Item $file).LastWriteTimeUtc = $touchTime }\n}\n",[2678],{"type":40,"tag":200,"props":2679,"children":2680},{"__ignoreMap":237},[2681,2689,2697,2705],{"type":40,"tag":243,"props":2682,"children":2683},{"class":245,"line":246},[2684],{"type":40,"tag":243,"props":2685,"children":2686},{},[2687],{"type":46,"value":2688},"$touchTime = (Get-Date).ToUniversalTime()\n",{"type":40,"tag":243,"props":2690,"children":2691},{"class":245,"line":255},[2692],{"type":40,"tag":243,"props":2693,"children":2694},{},[2695],{"type":46,"value":2696},"foreach ($file in $tuFiles) {\n",{"type":40,"tag":243,"props":2698,"children":2699},{"class":245,"line":660},[2700],{"type":40,"tag":243,"props":2701,"children":2702},{},[2703],{"type":46,"value":2704},"    if (Test-Path $file) { (Get-Item $file).LastWriteTimeUtc = $touchTime }\n",{"type":40,"tag":243,"props":2706,"children":2707},{"class":245,"line":844},[2708],{"type":40,"tag":243,"props":2709,"children":2710},{},[2711],{"type":46,"value":958},{"type":40,"tag":70,"props":2713,"children":2715},{"id":2714},"step-3-pair-and-alternate-5-iterations-each-side",[2716],{"type":46,"value":2717},"Step 3 — Pair-and-alternate, 5 iterations each side",{"type":40,"tag":56,"props":2719,"children":2720},{},[2721,2723,2728,2730,2735,2737,2742,2744,2748],{"type":46,"value":2722},"Measured builds are ",{"type":40,"tag":62,"props":2724,"children":2725},{},[2726],{"type":46,"value":2727},"plain, uninstrumented, non-vcperf",{"type":46,"value":2729}," wall-clock builds (",{"type":40,"tag":200,"props":2731,"children":2733},{"className":2732},[],[2734],{"type":46,"value":2437},{"type":46,"value":2736}," \u002F ",{"type":40,"tag":200,"props":2738,"children":2740},{"className":2739},[],[2741],{"type":46,"value":2444},{"type":46,"value":2743},"), recorded in ",{"type":40,"tag":62,"props":2745,"children":2746},{},[2747],{"type":46,"value":2451},{"type":46,"value":151},{"type":40,"tag":56,"props":2750,"children":2751},{},[2752],{"type":46,"value":2753},"For each iteration:",{"type":40,"tag":87,"props":2755,"children":2756},{},[2757,2791],{"type":40,"tag":91,"props":2758,"children":2759},{},[2760,2762,2767,2769,2775,2777,2782,2784,2789],{"type":46,"value":2761},"Ensure candidate changes are ",{"type":40,"tag":62,"props":2763,"children":2764},{},[2765],{"type":46,"value":2766},"applied",{"type":46,"value":2768}," (",{"type":40,"tag":200,"props":2770,"children":2772},{"className":2771},[],[2773],{"type":46,"value":2774},"git stash pop",{"type":46,"value":2776}," or be on the change branch); run a regular build to settle ",{"type":40,"tag":200,"props":2778,"children":2780},{"className":2779},[],[2781],{"type":46,"value":2545},{"type":46,"value":2783}," state; touch the chosen TUs; run an uninstrumented incremental build. Record as ",{"type":40,"tag":62,"props":2785,"children":2786},{},[2787],{"type":46,"value":2788},"A",{"type":46,"value":2790}," (with changes).",{"type":40,"tag":91,"props":2792,"children":2793},{},[2794,2799,2801,2807,2809,2814,2816,2821],{"type":40,"tag":62,"props":2795,"children":2796},{},[2797],{"type":46,"value":2798},"Revert",{"type":46,"value":2800}," candidate changes (",{"type":40,"tag":200,"props":2802,"children":2804},{"className":2803},[],[2805],{"type":46,"value":2806},"git stash",{"type":46,"value":2808}," or switch to base branch); run a regular build to settle ",{"type":40,"tag":200,"props":2810,"children":2812},{"className":2811},[],[2813],{"type":46,"value":2545},{"type":46,"value":2815}," state; touch the same TUs; run an uninstrumented incremental build. Record as ",{"type":40,"tag":62,"props":2817,"children":2818},{},[2819],{"type":46,"value":2820},"B",{"type":46,"value":2822}," (baseline).",{"type":40,"tag":56,"props":2824,"children":2825},{},[2826,2828,2833,2835,2840],{"type":46,"value":2827},"The \"settle ",{"type":40,"tag":200,"props":2829,"children":2831},{"className":2830},[],[2832],{"type":46,"value":2545},{"type":46,"value":2834}," state\" build after each switch is mandatory — skip it and A and B compile different amounts of code. ",{"type":40,"tag":62,"props":2836,"children":2837},{},[2838],{"type":46,"value":2839},"Alternate",{"type":46,"value":2841}," A and B per iteration (not 5 As then 5 Bs) to average out warm-cache and thermal effects.",{"type":40,"tag":70,"props":2843,"children":2845},{"id":2844},"step-4-compare-and-report",[2846],{"type":46,"value":2847},"Step 4 — Compare and report",{"type":40,"tag":56,"props":2849,"children":2850},{},[2851,2853,2859,2861,2865,2867,2873],{"type":46,"value":2852},"Meaningful improvement is ",{"type":40,"tag":200,"props":2854,"children":2856},{"className":2855},[],[2857],{"type":46,"value":2858},"A_avg \u003C B_avg - B_stddev",{"type":46,"value":2860}," (same rule as the rebuild baseline). Report all times in ",{"type":40,"tag":62,"props":2862,"children":2863},{},[2864],{"type":46,"value":2451},{"type":46,"value":2866}," with the standard deviation in its own column (no ",{"type":40,"tag":200,"props":2868,"children":2870},{"className":2869},[],[2871],{"type":46,"value":2872},"mean ± stddev",{"type":46,"value":2874}," shorthand):",{"type":40,"tag":1495,"props":2876,"children":2877},{},[2878,2899],{"type":40,"tag":1499,"props":2879,"children":2880},{},[2881],{"type":40,"tag":1503,"props":2882,"children":2883},{},[2884,2889,2894],{"type":40,"tag":1507,"props":2885,"children":2886},{},[2887],{"type":46,"value":2888},"Variant",{"type":40,"tag":1507,"props":2890,"children":2891},{},[2892],{"type":46,"value":2893},"Mean (s)",{"type":40,"tag":1507,"props":2895,"children":2896},{},[2897],{"type":46,"value":2898},"StdDev (s)",{"type":40,"tag":1518,"props":2900,"children":2901},{},[2902,2919],{"type":40,"tag":1503,"props":2903,"children":2904},{},[2905,2910,2915],{"type":40,"tag":1525,"props":2906,"children":2907},{},[2908],{"type":46,"value":2909},"A (with changes)",{"type":40,"tag":1525,"props":2911,"children":2912},{},[2913],{"type":46,"value":2914},"...",{"type":40,"tag":1525,"props":2916,"children":2917},{},[2918],{"type":46,"value":2914},{"type":40,"tag":1503,"props":2920,"children":2921},{},[2922,2927,2931],{"type":40,"tag":1525,"props":2923,"children":2924},{},[2925],{"type":46,"value":2926},"B (baseline)",{"type":40,"tag":1525,"props":2928,"children":2929},{},[2930],{"type":46,"value":2914},{"type":40,"tag":1525,"props":2932,"children":2933},{},[2934],{"type":46,"value":2914},{"type":40,"tag":56,"props":2936,"children":2937},{},[2938,2940,2946,2948,2954],{"type":46,"value":2939},"Also report the number of TUs touched, ",{"type":40,"tag":200,"props":2941,"children":2943},{"className":2942},[],[2944],{"type":46,"value":2945},"delta_s = B_avg - A_avg",{"type":46,"value":2947}," (positive = improvement), and ",{"type":40,"tag":200,"props":2949,"children":2951},{"className":2950},[],[2952],{"type":46,"value":2953},"delta_pct = delta_s \u002F B_avg * 100",{"type":46,"value":151},{"type":40,"tag":49,"props":2956,"children":2958},{"id":2957},"git-history-rules",[2959],{"type":46,"value":2960},"Git History Rules",{"type":40,"tag":56,"props":2962,"children":2963},{},[2964,2969,2971,2975],{"type":40,"tag":62,"props":2965,"children":2966},{},[2967],{"type":46,"value":2968},"CRITICAL:",{"type":46,"value":2970}," Do not use git history (log, blame, diff) for commits ",{"type":40,"tag":62,"props":2972,"children":2973},{},[2974],{"type":46,"value":1222},{"type":46,"value":2976}," the branch fork-point (merge-base with the base branch). Build performance analysis evaluates the current state of the code — post-fork-point history can bias optimization decisions.",{"type":40,"tag":56,"props":2978,"children":2979},{},[2980,2982,2986],{"type":46,"value":2981},"You MAY use git history for commits ",{"type":40,"tag":62,"props":2983,"children":2984},{},[2985],{"type":46,"value":107},{"type":46,"value":2987}," the fork-point to understand:",{"type":40,"tag":518,"props":2989,"children":2990},{},[2991,2996,3001],{"type":40,"tag":91,"props":2992,"children":2993},{},[2994],{"type":46,"value":2995},"When a header was introduced or significantly changed.",{"type":40,"tag":91,"props":2997,"children":2998},{},[2999],{"type":46,"value":3000},"Historical context for why a particular include structure exists.",{"type":40,"tag":91,"props":3002,"children":3003},{},[3004],{"type":46,"value":3005},"Whether a PCH previously existed and was removed.",{"type":40,"tag":49,"props":3007,"children":3009},{"id":3008},"remediation-strategies",[3010],{"type":46,"value":160},{"type":40,"tag":56,"props":3012,"children":3013},{},[3014,3016,3021,3023,3028],{"type":46,"value":3015},"After producing a JSON analysis report and ",{"type":40,"tag":62,"props":3017,"children":3018},{},[3019],{"type":46,"value":3020},"applying the selection rules above",{"type":46,"value":3022},", use the strategies below to fix each category. Always ",{"type":40,"tag":62,"props":3024,"children":3025},{},[3026],{"type":46,"value":3027},"re-profile after each change",{"type":46,"value":3029}," to verify improvement and catch regressions.",{"type":40,"tag":70,"props":3031,"children":3033},{"id":3032},"expensive-included-files-includedfiles",[3034,3036,3041],{"type":46,"value":3035},"Expensive Included Files (",{"type":40,"tag":200,"props":3037,"children":3039},{"className":3038},[],[3040],{"type":46,"value":1703},{"type":46,"value":3042},")",{"type":40,"tag":56,"props":3044,"children":3045},{},[3046],{"type":46,"value":3047},"Headers with high WCTR and high include counts are the highest-leverage targets. A header included in N translation units has its parse cost multiplied N times.",{"type":40,"tag":1672,"props":3049,"children":3051},{"id":3050},"strategy-1-use-or-create-a-precompiled-header-pch",[3052],{"type":46,"value":3053},"Strategy 1 — Use or create a precompiled header (PCH)",{"type":40,"tag":56,"props":3055,"children":3056},{},[3057],{"type":46,"value":3058},"A PCH parses expensive headers once and reuses the result across all translation\nunits. This is the single most effective technique for headers that are both\nexpensive and widely included.",{"type":40,"tag":56,"props":3060,"children":3061},{},[3062],{"type":40,"tag":62,"props":3063,"children":3064},{},[3065],{"type":46,"value":3066},"When to use:",{"type":40,"tag":518,"props":3068,"children":3069},{},[3070,3075,3109,3114],{"type":40,"tag":91,"props":3071,"children":3072},{},[3073],{"type":46,"value":3074},"Headers with high WCTR, high include count, and low change frequency.",{"type":40,"tag":91,"props":3076,"children":3077},{},[3078,3080,3086,3087,3093,3094,3100,3101,3107],{"type":46,"value":3079},"STL headers (",{"type":40,"tag":200,"props":3081,"children":3083},{"className":3082},[],[3084],{"type":46,"value":3085},"\u003Cstring>",{"type":46,"value":1705},{"type":40,"tag":200,"props":3088,"children":3090},{"className":3089},[],[3091],{"type":46,"value":3092},"\u003Cvector>",{"type":46,"value":1705},{"type":40,"tag":200,"props":3095,"children":3097},{"className":3096},[],[3098],{"type":46,"value":3099},"\u003Cmap>",{"type":46,"value":1705},{"type":40,"tag":200,"props":3102,"children":3104},{"className":3103},[],[3105],{"type":46,"value":3106},"\u003Cmemory>",{"type":46,"value":3108},", etc.) are ideal\nbecause they never change.",{"type":40,"tag":91,"props":3110,"children":3111},{},[3112],{"type":46,"value":3113},"Third-party library headers (GLM, SDL, fmt, etc.) are excellent candidates.",{"type":40,"tag":91,"props":3115,"children":3116},{},[3117],{"type":46,"value":3118},"Stable project headers that are included in many TUs but rarely modified.",{"type":40,"tag":56,"props":3120,"children":3121},{},[3122],{"type":40,"tag":62,"props":3123,"children":3124},{},[3125],{"type":46,"value":3126},"How to evaluate project headers for PCH inclusion:",{"type":40,"tag":87,"props":3128,"children":3129},{},[3130,3135],{"type":40,"tag":91,"props":3131,"children":3132},{},[3133],{"type":46,"value":3134},"Check the header's WCTR and include count from the JSON report.",{"type":40,"tag":91,"props":3136,"children":3137},{},[3138,3140],{"type":46,"value":3139},"Check change frequency: ",{"type":40,"tag":200,"props":3141,"children":3143},{"className":3142},[],[3144],{"type":46,"value":3145},"git log --oneline --since=\"1 year ago\" -- path\u002Fto\u002Fheader.hpp",{"type":40,"tag":56,"props":3147,"children":3148},{},[3149],{"type":40,"tag":62,"props":3150,"children":3151},{},[3152],{"type":46,"value":3153},"PCH header selection tiers:",{"type":40,"tag":1495,"props":3155,"children":3156},{},[3157,3183],{"type":40,"tag":1499,"props":3158,"children":3159},{},[3160],{"type":40,"tag":1503,"props":3161,"children":3162},{},[3163,3168,3173,3178],{"type":40,"tag":1507,"props":3164,"children":3165},{},[3166],{"type":46,"value":3167},"Tier",{"type":40,"tag":1507,"props":3169,"children":3170},{},[3171],{"type":46,"value":3172},"Type",{"type":40,"tag":1507,"props":3174,"children":3175},{},[3176],{"type":46,"value":3177},"Example",{"type":40,"tag":1507,"props":3179,"children":3180},{},[3181],{"type":46,"value":3182},"Risk",{"type":40,"tag":1518,"props":3184,"children":3185},{},[3186,3218,3252,3275],{"type":40,"tag":1503,"props":3187,"children":3188},{},[3189,3194,3199,3213],{"type":40,"tag":1525,"props":3190,"children":3191},{},[3192],{"type":46,"value":3193},"1 (always safe)",{"type":40,"tag":1525,"props":3195,"children":3196},{},[3197],{"type":46,"value":3198},"STL headers",{"type":40,"tag":1525,"props":3200,"children":3201},{},[3202,3207,3208],{"type":40,"tag":200,"props":3203,"children":3205},{"className":3204},[],[3206],{"type":46,"value":3085},{"type":46,"value":1705},{"type":40,"tag":200,"props":3209,"children":3211},{"className":3210},[],[3212],{"type":46,"value":3092},{"type":40,"tag":1525,"props":3214,"children":3215},{},[3216],{"type":46,"value":3217},"None — never change",{"type":40,"tag":1503,"props":3219,"children":3220},{},[3221,3226,3231,3247],{"type":40,"tag":1525,"props":3222,"children":3223},{},[3224],{"type":46,"value":3225},"2 (safe)",{"type":40,"tag":1525,"props":3227,"children":3228},{},[3229],{"type":46,"value":3230},"Third-party",{"type":40,"tag":1525,"props":3232,"children":3233},{},[3234,3240,3241],{"type":40,"tag":200,"props":3235,"children":3237},{"className":3236},[],[3238],{"type":46,"value":3239},"\u003Cglm\u002Fglm.hpp>",{"type":46,"value":1705},{"type":40,"tag":200,"props":3242,"children":3244},{"className":3243},[],[3245],{"type":46,"value":3246},"\u003CSDL.h>",{"type":40,"tag":1525,"props":3248,"children":3249},{},[3250],{"type":46,"value":3251},"Low — change only on dependency upgrade",{"type":40,"tag":1503,"props":3253,"children":3254},{},[3255,3260,3265,3270],{"type":40,"tag":1525,"props":3256,"children":3257},{},[3258],{"type":46,"value":3259},"3 (evaluate)",{"type":40,"tag":1525,"props":3261,"children":3262},{},[3263],{"type":46,"value":3264},"Stable project",{"type":40,"tag":1525,"props":3266,"children":3267},{},[3268],{"type":46,"value":3269},"Core type headers, rendering API",{"type":40,"tag":1525,"props":3271,"children":3272},{},[3273],{"type":46,"value":3274},"Medium — check git history first",{"type":40,"tag":1503,"props":3276,"children":3277},{},[3278,3283,3288,3293],{"type":40,"tag":1525,"props":3279,"children":3280},{},[3281],{"type":46,"value":3282},"4 (avoid)",{"type":40,"tag":1525,"props":3284,"children":3285},{},[3286],{"type":46,"value":3287},"Volatile project",{"type":40,"tag":1525,"props":3289,"children":3290},{},[3291],{"type":46,"value":3292},"Actively developed feature headers",{"type":40,"tag":1525,"props":3294,"children":3295},{},[3296],{"type":46,"value":3297},"High — triggers frequent full rebuilds",{"type":40,"tag":56,"props":3299,"children":3300},{},[3301,3303],{"type":46,"value":3302},"If the PCH change already shows a statistically significant clean-rebuild improvement, ",{"type":40,"tag":62,"props":3304,"children":3305},{},[3306],{"type":46,"value":3307},"the change is validated — do not run the iterative workflow.",{"type":40,"tag":1672,"props":3309,"children":3311},{"id":3310},"strategy-2-use-forward-declarations",[3312],{"type":46,"value":3313},"Strategy 2 — Use forward declarations",{"type":40,"tag":56,"props":3315,"children":3316},{},[3317],{"type":46,"value":3318},"If a header only uses pointers or references to a type, it does not need the full definition — a forward declaration suffices.",{"type":40,"tag":87,"props":3320,"children":3321},{},[3322,3365,3385],{"type":40,"tag":91,"props":3323,"children":3324},{},[3325,3327,3333,3334,3340,3342,3348,3349,3355,3357,3363],{"type":46,"value":3326},"In headers, replace ",{"type":40,"tag":200,"props":3328,"children":3330},{"className":3329},[],[3331],{"type":46,"value":3332},"#include \"foo.hpp\"",{"type":46,"value":991},{"type":40,"tag":200,"props":3335,"children":3337},{"className":3336},[],[3338],{"type":46,"value":3339},"class Foo;",{"type":46,"value":3341}," when only ",{"type":40,"tag":200,"props":3343,"children":3345},{"className":3344},[],[3346],{"type":46,"value":3347},"Foo*",{"type":46,"value":1705},{"type":40,"tag":200,"props":3350,"children":3352},{"className":3351},[],[3353],{"type":46,"value":3354},"Foo&",{"type":46,"value":3356},", or ",{"type":40,"tag":200,"props":3358,"children":3360},{"className":3359},[],[3361],{"type":46,"value":3362},"std::unique_ptr\u003CFoo>",{"type":46,"value":3364}," are used.",{"type":40,"tag":91,"props":3366,"children":3367},{},[3368,3370,3375,3377,3383],{"type":46,"value":3369},"Move ",{"type":40,"tag":200,"props":3371,"children":3373},{"className":3372},[],[3374],{"type":46,"value":3332},{"type":46,"value":3376}," to the ",{"type":40,"tag":200,"props":3378,"children":3380},{"className":3379},[],[3381],{"type":46,"value":3382},".cpp",{"type":46,"value":3384}," file where the full definition is needed.",{"type":40,"tag":91,"props":3386,"children":3387},{},[3388,3390,3396],{"type":46,"value":3389},"Consider a project ",{"type":40,"tag":200,"props":3391,"children":3393},{"className":3392},[],[3394],{"type":46,"value":3395},"fwd.hpp",{"type":46,"value":3397}," that collects common forward declarations for widely-used types.",{"type":40,"tag":1672,"props":3399,"children":3401},{"id":3400},"strategy-3-flatten-include-chains",[3402],{"type":46,"value":3403},"Strategy 3 — Flatten include chains",{"type":40,"tag":56,"props":3405,"children":3406},{},[3407],{"type":46,"value":3408},"Deeply nested include chains amplify costs. If header A includes B which includes C which includes D, every file that includes A pays for all four.",{"type":40,"tag":87,"props":3410,"children":3411},{},[3412,3423,3428],{"type":40,"tag":91,"props":3413,"children":3414},{},[3415,3416,3421],{"type":46,"value":1610},{"type":40,"tag":200,"props":3417,"children":3419},{"className":3418},[],[3420],{"type":46,"value":2301},{"type":46,"value":3422}," to identify deep chains.",{"type":40,"tag":91,"props":3424,"children":3425},{},[3426],{"type":46,"value":3427},"Audit intermediate headers — do they really need everything they include?",{"type":40,"tag":91,"props":3429,"children":3430},{},[3431],{"type":46,"value":3432},"Break long chains by removing unnecessary intermediate includes; have consumers include what they need directly.",{"type":40,"tag":2305,"props":3434,"children":3435},{},[],{"type":40,"tag":70,"props":3437,"children":3439},{"id":3438},"expensive-functions-functions",[3440,3442,3447],{"type":46,"value":3441},"Expensive Functions (",{"type":40,"tag":200,"props":3443,"children":3445},{"className":3444},[],[3446],{"type":46,"value":1695},{"type":46,"value":3042},{"type":40,"tag":56,"props":3449,"children":3450},{},[3451],{"type":46,"value":3452},"Functions with high WCTR are expensive during the back-end code generation (compilation\u002Flinking) phase.",{"type":40,"tag":1672,"props":3454,"children":3456},{"id":3455},"strategy-1-reduce-__forceinline-and-excessive-inlining",[3457,3459,3465],{"type":46,"value":3458},"Strategy 1 — Reduce ",{"type":40,"tag":200,"props":3460,"children":3462},{"className":3461},[],[3463],{"type":46,"value":3464},"__forceinline",{"type":46,"value":3466}," and excessive inlining",{"type":40,"tag":56,"props":3468,"children":3469},{},[3470,3471,3477],{"type":46,"value":198},{"type":40,"tag":200,"props":3472,"children":3474},{"className":3473},[],[3475],{"type":46,"value":3476},"forceinlineSize",{"type":46,"value":3478}," field reveals how much code is inlined into each function. The larger this value relative to other entries in the post-filter top-15, the more aggressive inlining has bloated the function's body.",{"type":40,"tag":87,"props":3480,"children":3481},{},[3482,3494,3534,3546,3572],{"type":40,"tag":91,"props":3483,"children":3484},{},[3485,3487,3492],{"type":46,"value":3486},"Compare ",{"type":40,"tag":200,"props":3488,"children":3490},{"className":3489},[],[3491],{"type":46,"value":3476},{"type":46,"value":3493}," across the top-15 entries — the entries at the top of the weighted ranking are the ones whose inline bloat is paying off the least.",{"type":40,"tag":91,"props":3495,"children":3496},{},[3497,3499,3504,3505,3511,3513,3519,3521,3532],{"type":46,"value":3498},"Find functions or methods marked ",{"type":40,"tag":200,"props":3500,"children":3502},{"className":3501},[],[3503],{"type":46,"value":3464},{"type":46,"value":1705},{"type":40,"tag":200,"props":3506,"children":3508},{"className":3507},[],[3509],{"type":46,"value":3510},"__attribute__((always_inline))",{"type":46,"value":3512},", or defined in headers as ",{"type":40,"tag":200,"props":3514,"children":3516},{"className":3515},[],[3517],{"type":46,"value":3518},"inline",{"type":46,"value":3520}," that are called from the expensive function. ",{"type":40,"tag":62,"props":3522,"children":3523},{},[3524,3526],{"type":46,"value":3525},"Use the demangled ",{"type":40,"tag":200,"props":3527,"children":3529},{"className":3528},[],[3530],{"type":46,"value":3531},"functionName",{"type":46,"value":3533}," — the raw JSON name is decorated and will not match source-text grep.",{"type":40,"tag":91,"props":3535,"children":3536},{},[3537,3539,3544],{"type":46,"value":3538},"Move large inline function bodies from headers to ",{"type":40,"tag":200,"props":3540,"children":3542},{"className":3541},[],[3543],{"type":46,"value":3382},{"type":46,"value":3545}," files (see Strategy 3 below).",{"type":40,"tag":91,"props":3547,"children":3548},{},[3549,3551,3556,3558,3563,3565,3570],{"type":46,"value":3550},"Replace ",{"type":40,"tag":200,"props":3552,"children":3554},{"className":3553},[],[3555],{"type":46,"value":3464},{"type":46,"value":3557}," with regular ",{"type":40,"tag":200,"props":3559,"children":3561},{"className":3560},[],[3562],{"type":46,"value":3518},{"type":46,"value":3564}," or no annotation — let the compiler decide. Reserve ",{"type":40,"tag":200,"props":3566,"children":3568},{"className":3567},[],[3569],{"type":46,"value":3464},{"type":46,"value":3571}," for genuinely tiny, hot-path functions.",{"type":40,"tag":91,"props":3573,"children":3574},{},[3575,3577,3582],{"type":46,"value":3576},"For template-heavy code, consider explicit template instantiation in a ",{"type":40,"tag":200,"props":3578,"children":3580},{"className":3579},[],[3581],{"type":46,"value":3382},{"type":46,"value":3583}," file to avoid redundant codegen across TUs.",{"type":40,"tag":1672,"props":3585,"children":3587},{"id":3586},"strategy-2-break-up-large-functions",[3588],{"type":46,"value":3589},"Strategy 2 — Break up large functions",{"type":40,"tag":56,"props":3591,"children":3592},{},[3593],{"type":46,"value":3594},"Very large functions are expensive to optimize (register allocation, instruction scheduling, etc.).",{"type":40,"tag":87,"props":3596,"children":3597},{},[3598,3611,3616,3636],{"type":40,"tag":91,"props":3599,"children":3600},{},[3601,3603,3609],{"type":46,"value":3602},"Identify functions among the post-filter top-15 whose ",{"type":40,"tag":200,"props":3604,"children":3606},{"className":3605},[],[3607],{"type":46,"value":3608},"wallClockMillisecondTimeResponsibility",{"type":46,"value":3610}," is large relative to others in the list. The relative ranking is the signal — there is no absolute time cutoff.",{"type":40,"tag":91,"props":3612,"children":3613},{},[3614],{"type":46,"value":3615},"Extract logically independent sections into separate helper functions.",{"type":40,"tag":91,"props":3617,"children":3618},{},[3619,3621,3627,3628,3634],{"type":46,"value":3620},"Move cold paths (error handling, logging, rare branches) into separate ",{"type":40,"tag":200,"props":3622,"children":3624},{"className":3623},[],[3625],{"type":46,"value":3626},"__declspec(noinline)",{"type":46,"value":432},{"type":40,"tag":200,"props":3629,"children":3631},{"className":3630},[],[3632],{"type":46,"value":3633},"[[gnu::noinline]]",{"type":46,"value":3635}," functions to reduce optimizer workload on the hot path.",{"type":40,"tag":91,"props":3637,"children":3638},{},[3639,3651,3652,3657],{"type":40,"tag":62,"props":3640,"children":3641},{},[3642,3644,3650],{"type":46,"value":3643},"Prefer breaking up before marking ",{"type":40,"tag":200,"props":3645,"children":3647},{"className":3646},[],[3648],{"type":46,"value":3649},"noinline",{"type":46,"value":151},{"type":46,"value":2190},{"type":40,"tag":200,"props":3653,"children":3655},{"className":3654},[],[3656],{"type":46,"value":3649},{"type":46,"value":3658}," is the last-resort hammer.",{"type":40,"tag":1672,"props":3660,"children":3662},{"id":3661},"strategy-3-keep-the-implementation-private-to-the-cpp-file",[3663,3665,3670],{"type":46,"value":3664},"Strategy 3 — Keep the implementation private to the ",{"type":40,"tag":200,"props":3666,"children":3668},{"className":3667},[],[3669],{"type":46,"value":3382},{"type":46,"value":3671}," file",{"type":40,"tag":56,"props":3673,"children":3674},{},[3675,3677,3682,3684,3689,3691,3697],{"type":46,"value":3676},"A function body defined inside a class declaration (or marked ",{"type":40,"tag":200,"props":3678,"children":3680},{"className":3679},[],[3681],{"type":46,"value":3518},{"type":46,"value":3683}," in a header) is implicitly inline: every TU that includes the header parses the body and instantiates every template it touches, even TUs that never call the function. Moving the body to the ",{"type":40,"tag":200,"props":3685,"children":3687},{"className":3686},[],[3688],{"type":46,"value":3382},{"type":46,"value":3690}," file pays each cost exactly once. This matters most when the inline body uses STL algorithms or other heavily templated code — each ",{"type":40,"tag":200,"props":3692,"children":3694},{"className":3693},[],[3695],{"type":46,"value":3696},"#include",{"type":46,"value":3698}," of the header re-instantiates those templates.",{"type":40,"tag":56,"props":3700,"children":3701},{},[3702],{"type":40,"tag":62,"props":3703,"children":3704},{},[3705],{"type":46,"value":3706},"Anti-pattern — body defined inline in the header:",{"type":40,"tag":232,"props":3708,"children":3712},{"className":3709,"code":3710,"language":3711,"meta":237,"style":237},"language-cpp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F ----- foo.h -----\n#include \u003Calgorithm>   \u002F\u002F ← every consumer of foo.h pays for \u003Calgorithm>\n#include \u003Cstring>\n\nclass foo\n{\n    foo(std::string str)\n    {\n        std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\n        \u002F\u002F std::find_if is instantiated in EVERY TU that includes foo.h.\n    }\n    void bar();\n};\n\n\u002F\u002F ----- foo.cpp -----\n#include \"foo.h\"\nvoid foo::bar() { }\n","cpp",[3713],{"type":40,"tag":200,"props":3714,"children":3715},{"__ignoreMap":237},[3716,3724,3737,3745,3752,3760,3768,3776,3784,3792,3800,3807,3815,3823,3830,3838,3846],{"type":40,"tag":243,"props":3717,"children":3718},{"class":245,"line":246},[3719],{"type":40,"tag":243,"props":3720,"children":3721},{},[3722],{"type":46,"value":3723},"\u002F\u002F ----- foo.h -----\n",{"type":40,"tag":243,"props":3725,"children":3726},{"class":245,"line":255},[3727,3732],{"type":40,"tag":243,"props":3728,"children":3729},{},[3730],{"type":46,"value":3731},"#include \u003Calgorithm>",{"type":40,"tag":243,"props":3733,"children":3734},{},[3735],{"type":46,"value":3736},"   \u002F\u002F ← every consumer of foo.h pays for \u003Calgorithm>\n",{"type":40,"tag":243,"props":3738,"children":3739},{"class":245,"line":660},[3740],{"type":40,"tag":243,"props":3741,"children":3742},{},[3743],{"type":46,"value":3744},"#include \u003Cstring>\n",{"type":40,"tag":243,"props":3746,"children":3747},{"class":245,"line":844},[3748],{"type":40,"tag":243,"props":3749,"children":3750},{"emptyLinePlaceholder":1283},[3751],{"type":46,"value":1286},{"type":40,"tag":243,"props":3753,"children":3754},{"class":245,"line":853},[3755],{"type":40,"tag":243,"props":3756,"children":3757},{},[3758],{"type":46,"value":3759},"class foo\n",{"type":40,"tag":243,"props":3761,"children":3762},{"class":245,"line":862},[3763],{"type":40,"tag":243,"props":3764,"children":3765},{},[3766],{"type":46,"value":3767},"{\n",{"type":40,"tag":243,"props":3769,"children":3770},{"class":245,"line":871},[3771],{"type":40,"tag":243,"props":3772,"children":3773},{},[3774],{"type":46,"value":3775},"    foo(std::string str)\n",{"type":40,"tag":243,"props":3777,"children":3778},{"class":245,"line":880},[3779],{"type":40,"tag":243,"props":3780,"children":3781},{},[3782],{"type":46,"value":3783},"    {\n",{"type":40,"tag":243,"props":3785,"children":3786},{"class":245,"line":889},[3787],{"type":40,"tag":243,"props":3788,"children":3789},{},[3790],{"type":46,"value":3791},"        std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\n",{"type":40,"tag":243,"props":3793,"children":3794},{"class":245,"line":898},[3795],{"type":40,"tag":243,"props":3796,"children":3797},{},[3798],{"type":46,"value":3799},"        \u002F\u002F std::find_if is instantiated in EVERY TU that includes foo.h.\n",{"type":40,"tag":243,"props":3801,"children":3802},{"class":245,"line":907},[3803],{"type":40,"tag":243,"props":3804,"children":3805},{},[3806],{"type":46,"value":949},{"type":40,"tag":243,"props":3808,"children":3809},{"class":245,"line":916},[3810],{"type":40,"tag":243,"props":3811,"children":3812},{},[3813],{"type":46,"value":3814},"    void bar();\n",{"type":40,"tag":243,"props":3816,"children":3817},{"class":245,"line":925},[3818],{"type":40,"tag":243,"props":3819,"children":3820},{},[3821],{"type":46,"value":3822},"};\n",{"type":40,"tag":243,"props":3824,"children":3825},{"class":245,"line":934},[3826],{"type":40,"tag":243,"props":3827,"children":3828},{"emptyLinePlaceholder":1283},[3829],{"type":46,"value":1286},{"type":40,"tag":243,"props":3831,"children":3832},{"class":245,"line":943},[3833],{"type":40,"tag":243,"props":3834,"children":3835},{},[3836],{"type":46,"value":3837},"\u002F\u002F ----- foo.cpp -----\n",{"type":40,"tag":243,"props":3839,"children":3840},{"class":245,"line":952},[3841],{"type":40,"tag":243,"props":3842,"children":3843},{},[3844],{"type":46,"value":3845},"#include \"foo.h\"\n",{"type":40,"tag":243,"props":3847,"children":3848},{"class":245,"line":961},[3849],{"type":40,"tag":243,"props":3850,"children":3851},{},[3852],{"type":46,"value":3853},"void foo::bar() { }\n",{"type":40,"tag":56,"props":3855,"children":3856},{},[3857],{"type":40,"tag":62,"props":3858,"children":3859},{},[3860,3862,3868],{"type":46,"value":3861},"Refactored — implementation private to ",{"type":40,"tag":200,"props":3863,"children":3865},{"className":3864},[],[3866],{"type":46,"value":3867},"foo.cpp",{"type":46,"value":516},{"type":40,"tag":232,"props":3870,"children":3872},{"className":3709,"code":3871,"language":3711,"meta":237,"style":237},"\u002F\u002F ----- foo.h -----\n#include \u003Cstring>\n\nclass foo\n{\n    foo(std::string str);   \u002F\u002F declaration only\n    void bar();\n};\n\n\u002F\u002F ----- foo.cpp -----\n#include \"foo.h\"\n#include \u003Calgorithm>   \u002F\u002F ← only foo.cpp pays for \u003Calgorithm> now\n\nfoo::foo(std::string str)\n{\n    std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\n}\n\nvoid foo::bar() { }\n",[3873],{"type":40,"tag":200,"props":3874,"children":3875},{"__ignoreMap":237},[3876,3883,3890,3897,3904,3911,3919,3926,3933,3940,3947,3954,3966,3973,3981,3988,3996,4003,4011],{"type":40,"tag":243,"props":3877,"children":3878},{"class":245,"line":246},[3879],{"type":40,"tag":243,"props":3880,"children":3881},{},[3882],{"type":46,"value":3723},{"type":40,"tag":243,"props":3884,"children":3885},{"class":245,"line":255},[3886],{"type":40,"tag":243,"props":3887,"children":3888},{},[3889],{"type":46,"value":3744},{"type":40,"tag":243,"props":3891,"children":3892},{"class":245,"line":660},[3893],{"type":40,"tag":243,"props":3894,"children":3895},{"emptyLinePlaceholder":1283},[3896],{"type":46,"value":1286},{"type":40,"tag":243,"props":3898,"children":3899},{"class":245,"line":844},[3900],{"type":40,"tag":243,"props":3901,"children":3902},{},[3903],{"type":46,"value":3759},{"type":40,"tag":243,"props":3905,"children":3906},{"class":245,"line":853},[3907],{"type":40,"tag":243,"props":3908,"children":3909},{},[3910],{"type":46,"value":3767},{"type":40,"tag":243,"props":3912,"children":3913},{"class":245,"line":862},[3914],{"type":40,"tag":243,"props":3915,"children":3916},{},[3917],{"type":46,"value":3918},"    foo(std::string str);   \u002F\u002F declaration only\n",{"type":40,"tag":243,"props":3920,"children":3921},{"class":245,"line":871},[3922],{"type":40,"tag":243,"props":3923,"children":3924},{},[3925],{"type":46,"value":3814},{"type":40,"tag":243,"props":3927,"children":3928},{"class":245,"line":880},[3929],{"type":40,"tag":243,"props":3930,"children":3931},{},[3932],{"type":46,"value":3822},{"type":40,"tag":243,"props":3934,"children":3935},{"class":245,"line":889},[3936],{"type":40,"tag":243,"props":3937,"children":3938},{"emptyLinePlaceholder":1283},[3939],{"type":46,"value":1286},{"type":40,"tag":243,"props":3941,"children":3942},{"class":245,"line":898},[3943],{"type":40,"tag":243,"props":3944,"children":3945},{},[3946],{"type":46,"value":3837},{"type":40,"tag":243,"props":3948,"children":3949},{"class":245,"line":907},[3950],{"type":40,"tag":243,"props":3951,"children":3952},{},[3953],{"type":46,"value":3845},{"type":40,"tag":243,"props":3955,"children":3956},{"class":245,"line":916},[3957,3961],{"type":40,"tag":243,"props":3958,"children":3959},{},[3960],{"type":46,"value":3731},{"type":40,"tag":243,"props":3962,"children":3963},{},[3964],{"type":46,"value":3965},"   \u002F\u002F ← only foo.cpp pays for \u003Calgorithm> now\n",{"type":40,"tag":243,"props":3967,"children":3968},{"class":245,"line":925},[3969],{"type":40,"tag":243,"props":3970,"children":3971},{"emptyLinePlaceholder":1283},[3972],{"type":46,"value":1286},{"type":40,"tag":243,"props":3974,"children":3975},{"class":245,"line":934},[3976],{"type":40,"tag":243,"props":3977,"children":3978},{},[3979],{"type":46,"value":3980},"foo::foo(std::string str)\n",{"type":40,"tag":243,"props":3982,"children":3983},{"class":245,"line":943},[3984],{"type":40,"tag":243,"props":3985,"children":3986},{},[3987],{"type":46,"value":3767},{"type":40,"tag":243,"props":3989,"children":3990},{"class":245,"line":952},[3991],{"type":40,"tag":243,"props":3992,"children":3993},{},[3994],{"type":46,"value":3995},"    std::find_if(str.begin(), str.end(), [](char c) { return c == 'ch'; });\n",{"type":40,"tag":243,"props":3997,"children":3998},{"class":245,"line":961},[3999],{"type":40,"tag":243,"props":4000,"children":4001},{},[4002],{"type":46,"value":958},{"type":40,"tag":243,"props":4004,"children":4006},{"class":245,"line":4005},18,[4007],{"type":40,"tag":243,"props":4008,"children":4009},{"emptyLinePlaceholder":1283},[4010],{"type":46,"value":1286},{"type":40,"tag":243,"props":4012,"children":4014},{"class":245,"line":4013},19,[4015],{"type":40,"tag":243,"props":4016,"children":4017},{},[4018],{"type":46,"value":3853},{"type":40,"tag":56,"props":4020,"children":4021},{},[4022,4028,4030,4036,4038,4043,4045,4051,4052,4057],{"type":40,"tag":200,"props":4023,"children":4025},{"className":4024},[],[4026],{"type":46,"value":4027},"\u003Calgorithm>",{"type":46,"value":4029}," and the ",{"type":40,"tag":200,"props":4031,"children":4033},{"className":4032},[],[4034],{"type":46,"value":4035},"std::find_if",{"type":46,"value":4037}," instantiation now occur once instead of once per TU. Combine with ",{"type":40,"tag":62,"props":4039,"children":4040},{},[4041],{"type":46,"value":4042},"Headers — Strategy 2 (forward declarations)",{"type":46,"value":4044}," to push more includes from ",{"type":40,"tag":200,"props":4046,"children":4048},{"className":4047},[],[4049],{"type":46,"value":4050},".h",{"type":46,"value":1346},{"type":40,"tag":200,"props":4053,"children":4055},{"className":4054},[],[4056],{"type":46,"value":3382},{"type":46,"value":151},{"type":40,"tag":56,"props":4059,"children":4060},{},[4061,4063,4068,4069,4075,4076,4082,4083,4089,4090,4096,4097,4103],{"type":46,"value":4062},"Apply when an inline header-defined body references heavy templated code (",{"type":40,"tag":200,"props":4064,"children":4066},{"className":4065},[],[4067],{"type":46,"value":4027},{"type":46,"value":1705},{"type":40,"tag":200,"props":4070,"children":4072},{"className":4071},[],[4073],{"type":46,"value":4074},"\u003Cregex>",{"type":46,"value":1705},{"type":40,"tag":200,"props":4077,"children":4079},{"className":4078},[],[4080],{"type":46,"value":4081},"\u003Cformat>",{"type":46,"value":1705},{"type":40,"tag":200,"props":4084,"children":4086},{"className":4085},[],[4087],{"type":46,"value":4088},"\u003Cranges>",{"type":46,"value":1705},{"type":40,"tag":200,"props":4091,"children":4093},{"className":4092},[],[4094],{"type":46,"value":4095},"\u003Cfilesystem>",{"type":46,"value":1705},{"type":40,"tag":200,"props":4098,"children":4100},{"className":4099},[],[4101],{"type":46,"value":4102},"\u003Cchrono>",{"type":46,"value":4104},") and the header is widely included. Skip for trivial accessors and templates themselves (their definitions must stay visible — use explicit instantiation, Strategy 1 step 5).",{"type":40,"tag":2305,"props":4106,"children":4107},{},[],{"type":40,"tag":70,"props":4109,"children":4111},{"id":4110},"expensive-templates-templates",[4112,4114,4119],{"type":46,"value":4113},"Expensive Templates (",{"type":40,"tag":200,"props":4115,"children":4117},{"className":4116},[],[4118],{"type":46,"value":1711},{"type":46,"value":3042},{"type":40,"tag":56,"props":4121,"children":4122},{},[4123,4125,4130,4131,4137,4139,4144],{"type":46,"value":4124},"Templates with high WCTR and high instantiation counts cause the compiler to repeat work across many TUs. Reminder: template WCTR is in ",{"type":40,"tag":62,"props":4126,"children":4127},{},[4128],{"type":46,"value":4129},"microseconds",{"type":46,"value":2768},{"type":40,"tag":200,"props":4132,"children":4134},{"className":4133},[],[4135],{"type":46,"value":4136},"wallClockMicrosecondTimeResponsibility",{"type":46,"value":4138},"); only the top ",{"type":40,"tag":62,"props":4140,"children":4141},{},[4142],{"type":46,"value":4143},"15",{"type":46,"value":4145}," entries are considered.",{"type":40,"tag":1672,"props":4147,"children":4149},{"id":4148},"strategy-1-reduce-instantiation-count",[4150],{"type":46,"value":4151},"Strategy 1 — Reduce instantiation count",{"type":40,"tag":87,"props":4153,"children":4154},{},[4155,4168,4188,4200],{"type":40,"tag":91,"props":4156,"children":4157},{},[4158,4160,4166],{"type":46,"value":4159},"Check ",{"type":40,"tag":200,"props":4161,"children":4163},{"className":4162},[],[4164],{"type":46,"value":4165},"instantiationCount",{"type":46,"value":4167}," — thousands of instantiations of the same template are a red flag.",{"type":40,"tag":91,"props":4169,"children":4170},{},[4171,4173,4179,4180,4186],{"type":46,"value":4172},"Identify whether the high count is from a project template or a standard library template (e.g. ",{"type":40,"tag":200,"props":4174,"children":4176},{"className":4175},[],[4177],{"type":46,"value":4178},"std::vector",{"type":46,"value":1705},{"type":40,"tag":200,"props":4181,"children":4183},{"className":4182},[],[4184],{"type":46,"value":4185},"std::unordered_map",{"type":46,"value":4187},").",{"type":40,"tag":91,"props":4189,"children":4190},{},[4191,4193,4198],{"type":46,"value":4192},"For ",{"type":40,"tag":62,"props":4194,"children":4195},{},[4196],{"type":46,"value":4197},"project templates",{"type":46,"value":4199},": limit distinct template arguments. Consider type-erased wrappers or base classes to reduce unique instantiations.",{"type":40,"tag":91,"props":4201,"children":4202},{},[4203,4204,4209],{"type":46,"value":4192},{"type":40,"tag":62,"props":4205,"children":4206},{},[4207],{"type":46,"value":4208},"STL templates",{"type":46,"value":4210},": typically unavoidable but mitigated by PCH (see above) since the compiler caches template definitions from precompiled headers.",{"type":40,"tag":1672,"props":4212,"children":4214},{"id":4213},"strategy-2-explicit-template-instantiation",[4215],{"type":46,"value":4216},"Strategy 2 — Explicit template instantiation",{"type":40,"tag":56,"props":4218,"children":4219},{},[4220],{"type":46,"value":4221},"For project templates instantiated with a known, finite set of types:",{"type":40,"tag":87,"props":4223,"children":4224},{},[4225,4277,4320],{"type":40,"tag":91,"props":4226,"children":4227},{},[4228,4230,4236,4238],{"type":46,"value":4229},"Declare the template as ",{"type":40,"tag":200,"props":4231,"children":4233},{"className":4232},[],[4234],{"type":46,"value":4235},"extern",{"type":46,"value":4237}," in the header:\n",{"type":40,"tag":232,"props":4239,"children":4241},{"className":3709,"code":4240,"language":3711,"meta":237,"style":237},"\u002F\u002F widget.hpp\ntemplate\u003Ctypename T> class Widget { \u002F* ... *\u002F };\nextern template class Widget\u003Cint>;\nextern template class Widget\u003Cfloat>;\n",[4242],{"type":40,"tag":200,"props":4243,"children":4244},{"__ignoreMap":237},[4245,4253,4261,4269],{"type":40,"tag":243,"props":4246,"children":4247},{"class":245,"line":246},[4248],{"type":40,"tag":243,"props":4249,"children":4250},{},[4251],{"type":46,"value":4252},"\u002F\u002F widget.hpp\n",{"type":40,"tag":243,"props":4254,"children":4255},{"class":245,"line":255},[4256],{"type":40,"tag":243,"props":4257,"children":4258},{},[4259],{"type":46,"value":4260},"template\u003Ctypename T> class Widget { \u002F* ... *\u002F };\n",{"type":40,"tag":243,"props":4262,"children":4263},{"class":245,"line":660},[4264],{"type":40,"tag":243,"props":4265,"children":4266},{},[4267],{"type":46,"value":4268},"extern template class Widget\u003Cint>;\n",{"type":40,"tag":243,"props":4270,"children":4271},{"class":245,"line":844},[4272],{"type":40,"tag":243,"props":4273,"children":4274},{},[4275],{"type":46,"value":4276},"extern template class Widget\u003Cfloat>;\n",{"type":40,"tag":91,"props":4278,"children":4279},{},[4280,4282,4287,4289],{"type":46,"value":4281},"Provide explicit instantiations in one ",{"type":40,"tag":200,"props":4283,"children":4285},{"className":4284},[],[4286],{"type":46,"value":3382},{"type":46,"value":4288}," file:\n",{"type":40,"tag":232,"props":4290,"children":4292},{"className":3709,"code":4291,"language":3711,"meta":237,"style":237},"\u002F\u002F widget.cpp\ntemplate class Widget\u003Cint>;\ntemplate class Widget\u003Cfloat>;\n",[4293],{"type":40,"tag":200,"props":4294,"children":4295},{"__ignoreMap":237},[4296,4304,4312],{"type":40,"tag":243,"props":4297,"children":4298},{"class":245,"line":246},[4299],{"type":40,"tag":243,"props":4300,"children":4301},{},[4302],{"type":46,"value":4303},"\u002F\u002F widget.cpp\n",{"type":40,"tag":243,"props":4305,"children":4306},{"class":245,"line":255},[4307],{"type":40,"tag":243,"props":4308,"children":4309},{},[4310],{"type":46,"value":4311},"template class Widget\u003Cint>;\n",{"type":40,"tag":243,"props":4313,"children":4314},{"class":245,"line":660},[4315],{"type":40,"tag":243,"props":4316,"children":4317},{},[4318],{"type":46,"value":4319},"template class Widget\u003Cfloat>;\n",{"type":40,"tag":91,"props":4321,"children":4322},{},[4323],{"type":46,"value":4324},"Each instantiation is now compiled once rather than in every TU that uses it.",{"type":40,"tag":1672,"props":4326,"children":4328},{"id":4327},"strategy-3-move-template-definitions-out-of-headers",[4329],{"type":46,"value":4330},"Strategy 3 — Move template definitions out of headers",{"type":40,"tag":87,"props":4332,"children":4333},{},[4334,4354],{"type":40,"tag":91,"props":4335,"children":4336},{},[4337,4339,4345,4346,4352],{"type":46,"value":4338},"If a template's implementation is large, keep only the declaration in the header and move the definition to a ",{"type":40,"tag":200,"props":4340,"children":4342},{"className":4341},[],[4343],{"type":46,"value":4344},".inl",{"type":46,"value":432},{"type":40,"tag":200,"props":4347,"children":4349},{"className":4348},[],[4350],{"type":46,"value":4351},".tpp",{"type":46,"value":4353}," file included only where needed.",{"type":40,"tag":91,"props":4355,"children":4356},{},[4357,4359,4364],{"type":46,"value":4358},"For templates used in only a few TUs, move the full definition to a ",{"type":40,"tag":200,"props":4360,"children":4362},{"className":4361},[],[4363],{"type":46,"value":3382},{"type":46,"value":4365}," file with explicit instantiations.",{"type":40,"tag":1672,"props":4367,"children":4369},{"id":4368},"strategy-4-simplify-template-metaprogramming",[4370],{"type":46,"value":4371},"Strategy 4 — Simplify template metaprogramming",{"type":40,"tag":87,"props":4373,"children":4374},{},[4375,4388,4401,4413],{"type":40,"tag":91,"props":4376,"children":4377},{},[4378,4380,4386],{"type":46,"value":4379},"Templates with deep recursion or heavy SFINAE\u002F",{"type":40,"tag":200,"props":4381,"children":4383},{"className":4382},[],[4384],{"type":46,"value":4385},"std::enable_if",{"type":46,"value":4387}," are expensive to instantiate.",{"type":40,"tag":91,"props":4389,"children":4390},{},[4391,4393,4399],{"type":46,"value":4392},"Prefer C++17 ",{"type":40,"tag":200,"props":4394,"children":4396},{"className":4395},[],[4397],{"type":46,"value":4398},"if constexpr",{"type":46,"value":4400}," over SFINAE for compile-time branching.",{"type":40,"tag":91,"props":4402,"children":4403},{},[4404,4406,4411],{"type":46,"value":4405},"Prefer C++20 concepts over complex ",{"type":40,"tag":200,"props":4407,"children":4409},{"className":4408},[],[4410],{"type":46,"value":4385},{"type":46,"value":4412}," chains.",{"type":40,"tag":91,"props":4414,"children":4415},{},[4416],{"type":46,"value":4417},"Reduce template nesting depth — flatten helper hierarchies.",{"type":40,"tag":2305,"props":4419,"children":4420},{},[],{"type":40,"tag":70,"props":4422,"children":4424},{"id":4423},"general-optimization-checklist",[4425],{"type":46,"value":4426},"General Optimization Checklist",{"type":40,"tag":56,"props":4428,"children":4429},{},[4430],{"type":46,"value":4431},"After profiling and before making changes, run through this checklist:",{"type":40,"tag":87,"props":4433,"children":4434},{},[4435,4468,4501],{"type":40,"tag":91,"props":4436,"children":4437},{},[4438,4443],{"type":40,"tag":62,"props":4439,"children":4440},{},[4441],{"type":46,"value":4442},"Quick wins (minutes, high impact):",{"type":40,"tag":518,"props":4444,"children":4445},{},[4446,4451,4463],{"type":40,"tag":91,"props":4447,"children":4448},{},[4449],{"type":46,"value":4450},"Remove umbrella\u002Fcatch-all includes from widely-included headers.",{"type":40,"tag":91,"props":4452,"children":4453},{},[4454,4456,4461],{"type":46,"value":4455},"Create or fix PCH with STL + ",{"type":40,"tag":62,"props":4457,"children":4458},{},[4459],{"type":46,"value":4460},"Tier-2 third-party umbrella headers",{"type":46,"value":4462}," (any heavily-included third-party \"include everything\" header your project uses). Missing these is a common cause of an under-performing PCH in projects built around third-party umbrella libraries.",{"type":40,"tag":91,"props":4464,"children":4465},{},[4466],{"type":46,"value":4467},"Add stable, widely-included project headers to the PCH (see Strategy 1's PCH header selection tiers above).",{"type":40,"tag":91,"props":4469,"children":4470},{},[4471,4476],{"type":40,"tag":62,"props":4472,"children":4473},{},[4474],{"type":46,"value":4475},"Medium effort (hours, moderate impact):",{"type":40,"tag":518,"props":4477,"children":4478},{},[4479,4484,4496],{"type":40,"tag":91,"props":4480,"children":4481},{},[4482],{"type":46,"value":4483},"Add forward declarations to headers that only use pointer\u002Freference types.",{"type":40,"tag":91,"props":4485,"children":4486},{},[4487,4489,4494],{"type":46,"value":4488},"Move large inline functions from headers to ",{"type":40,"tag":200,"props":4490,"children":4492},{"className":4491},[],[4493],{"type":46,"value":3382},{"type":46,"value":4495}," files.",{"type":40,"tag":91,"props":4497,"children":4498},{},[4499],{"type":46,"value":4500},"Use explicit template instantiation for common specializations.",{"type":40,"tag":91,"props":4502,"children":4503},{},[4504,4509],{"type":40,"tag":62,"props":4505,"children":4506},{},[4507],{"type":46,"value":4508},"Larger refactors (days, lower marginal impact):",{"type":40,"tag":518,"props":4510,"children":4511},{},[4512,4517,4522],{"type":40,"tag":91,"props":4513,"children":4514},{},[4515],{"type":46,"value":4516},"Split large TUs into smaller files.",{"type":40,"tag":91,"props":4518,"children":4519},{},[4520],{"type":46,"value":4521},"Flatten deep include chains.",{"type":40,"tag":91,"props":4523,"children":4524},{},[4525],{"type":46,"value":4526},"Replace heavy template metaprogramming with simpler alternatives.",{"type":40,"tag":56,"props":4528,"children":4529},{},[4530],{"type":46,"value":4531},"Always re-profile after each round of changes to measure improvement and confirm no regressions.",{"type":40,"tag":2305,"props":4533,"children":4534},{},[],{"type":40,"tag":49,"props":4536,"children":4538},{"id":4537},"measuring-final-performance-improvement",[4539],{"type":46,"value":178},{"type":40,"tag":56,"props":4541,"children":4542},{},[4543,4545,4550,4552,4556,4557],{"type":46,"value":4544},"This section defines ",{"type":40,"tag":62,"props":4546,"children":4547},{},[4548],{"type":46,"value":4549},"only the post-measurement decision logic and report format",{"type":46,"value":4551},". Measurement procedures live in ",{"type":40,"tag":95,"props":4553,"children":4554},{"href":132},[4555],{"type":46,"value":135},{"type":46,"value":476},{"type":40,"tag":95,"props":4558,"children":4559},{"href":183},[4560],{"type":46,"value":186},{"type":40,"tag":70,"props":4562,"children":4564},{"id":4563},"when-to-additionally-run-iterative-measurement",[4565],{"type":46,"value":4566},"When to additionally run iterative measurement",{"type":40,"tag":56,"props":4568,"children":4569},{},[4570,4572,4577],{"type":46,"value":4571},"After re-running a clean rebuild against the modified project, ",{"type":40,"tag":62,"props":4573,"children":4574},{},[4575],{"type":46,"value":4576},"skip iterative measurement when the clean rebuild already shows a statistically significant improvement",{"type":46,"value":4578}," — it adds 10+ extra timed builds and confirms nothing new.",{"type":40,"tag":56,"props":4580,"children":4581},{},[4582,4584,4588,4590,4595],{"type":46,"value":4583},"Otherwise, also run ",{"type":40,"tag":95,"props":4585,"children":4586},{"href":183},[4587],{"type":46,"value":186},{"type":46,"value":4589}," when ",{"type":40,"tag":62,"props":4591,"children":4592},{},[4593],{"type":46,"value":4594},"all",{"type":46,"value":4596}," of the following are true:",{"type":40,"tag":87,"props":4598,"children":4599},{},[4600,4612,4624],{"type":40,"tag":91,"props":4601,"children":4602},{},[4603,4605,4610],{"type":46,"value":4604},"The change added upfront compilation cost — specifically a ",{"type":40,"tag":62,"props":4606,"children":4607},{},[4608],{"type":46,"value":4609},"PCH",{"type":46,"value":4611}," or shared explicit template instantiation.",{"type":40,"tag":91,"props":4613,"children":4614},{},[4615,4617,4623],{"type":46,"value":4616},"The clean-rebuild result is neutral, regressed, or within ",{"type":40,"tag":200,"props":4618,"children":4620},{"className":4619},[],[4621],{"type":46,"value":4622},"baseline_average ± baseline_stddev",{"type":46,"value":151},{"type":40,"tag":91,"props":4625,"children":4626},{},[4627,4629,4634],{"type":46,"value":4628},"The change is theoretically sound based on the JSON analysis (e.g., a header used in many TUs was moved into a PCH and ",{"type":40,"tag":1638,"props":4630,"children":4631},{},[4632],{"type":46,"value":4633},"should",{"type":46,"value":4635}," amortize across iterative edits).",{"type":40,"tag":56,"props":4637,"children":4638},{},[4639,4641,4646],{"type":46,"value":4640},"A change is a ",{"type":40,"tag":62,"props":4642,"children":4643},{},[4644],{"type":46,"value":4645},"net win",{"type":46,"value":4647}," if either the clean-rebuild OR the iterative result is statistically significant and the other is at worst neutral.",{"type":40,"tag":70,"props":4649,"children":4651},{"id":4650},"summary-format",[4652],{"type":46,"value":4653},"Summary format",{"type":40,"tag":56,"props":4655,"children":4656},{},[4657,4662,4664,4669,4671,4676],{"type":40,"tag":62,"props":4658,"children":4659},{},[4660],{"type":46,"value":4661},"When validation ran",{"type":46,"value":4663},", report all times in seconds with mean and standard deviation in ",{"type":40,"tag":62,"props":4665,"children":4666},{},[4667],{"type":46,"value":4668},"separate columns",{"type":46,"value":4670}," — do not use the ",{"type":40,"tag":200,"props":4672,"children":4674},{"className":4673},[],[4675],{"type":46,"value":2872},{"type":46,"value":4677}," shorthand. Include both measurements when iterative ran. If you tried an approach that did not work and switched strategies, briefly state what you tried and why you moved on.",{"type":40,"tag":1495,"props":4679,"children":4680},{},[4681,4709],{"type":40,"tag":1499,"props":4682,"children":4683},{},[4684],{"type":40,"tag":1503,"props":4685,"children":4686},{},[4687,4692,4696,4700,4704],{"type":40,"tag":1507,"props":4688,"children":4689},{},[4690],{"type":46,"value":4691},"Measurement",{"type":40,"tag":1507,"props":4693,"children":4694},{},[4695],{"type":46,"value":2888},{"type":40,"tag":1507,"props":4697,"children":4698},{},[4699],{"type":46,"value":2893},{"type":40,"tag":1507,"props":4701,"children":4702},{},[4703],{"type":46,"value":2898},{"type":40,"tag":1507,"props":4705,"children":4706},{},[4707],{"type":46,"value":4708},"Delta %",{"type":40,"tag":1518,"props":4710,"children":4711},{},[4712,4738,4765,4790],{"type":40,"tag":1503,"props":4713,"children":4714},{},[4715,4720,4725,4730,4735],{"type":40,"tag":1525,"props":4716,"children":4717},{},[4718],{"type":46,"value":4719},"Clean rebuild",{"type":40,"tag":1525,"props":4721,"children":4722},{},[4723],{"type":46,"value":4724},"baseline",{"type":40,"tag":1525,"props":4726,"children":4727},{},[4728],{"type":46,"value":4729},"45.2",{"type":40,"tag":1525,"props":4731,"children":4732},{},[4733],{"type":46,"value":4734},"1.8",{"type":40,"tag":1525,"props":4736,"children":4737},{},[],{"type":40,"tag":1503,"props":4739,"children":4740},{},[4741,4745,4750,4755,4760],{"type":40,"tag":1525,"props":4742,"children":4743},{},[4744],{"type":46,"value":4719},{"type":40,"tag":1525,"props":4746,"children":4747},{},[4748],{"type":46,"value":4749},"post",{"type":40,"tag":1525,"props":4751,"children":4752},{},[4753],{"type":46,"value":4754},"47.1",{"type":40,"tag":1525,"props":4756,"children":4757},{},[4758],{"type":46,"value":4759},"1.5",{"type":40,"tag":1525,"props":4761,"children":4762},{},[4763],{"type":46,"value":4764},"-4.2% (regression)",{"type":40,"tag":1503,"props":4766,"children":4767},{},[4768,4773,4777,4782,4787],{"type":40,"tag":1525,"props":4769,"children":4770},{},[4771],{"type":46,"value":4772},"Iterative build",{"type":40,"tag":1525,"props":4774,"children":4775},{},[4776],{"type":46,"value":4724},{"type":40,"tag":1525,"props":4778,"children":4779},{},[4780],{"type":46,"value":4781},"8.4",{"type":40,"tag":1525,"props":4783,"children":4784},{},[4785],{"type":46,"value":4786},"0.3",{"type":40,"tag":1525,"props":4788,"children":4789},{},[],{"type":40,"tag":1503,"props":4791,"children":4792},{},[4793,4797,4801,4806,4811],{"type":40,"tag":1525,"props":4794,"children":4795},{},[4796],{"type":46,"value":4772},{"type":40,"tag":1525,"props":4798,"children":4799},{},[4800],{"type":46,"value":4749},{"type":40,"tag":1525,"props":4802,"children":4803},{},[4804],{"type":46,"value":4805},"3.1",{"type":40,"tag":1525,"props":4807,"children":4808},{},[4809],{"type":46,"value":4810},"0.2",{"type":40,"tag":1525,"props":4812,"children":4813},{},[4814],{"type":46,"value":4815},"+63.1% (significant)",{"type":40,"tag":56,"props":4817,"children":4818},{},[4819],{"type":46,"value":4820},"Decision: keep change — large iterative win outweighs small rebuild regression.",{"type":40,"tag":4822,"props":4823,"children":4824},"style",{},[4825],{"type":46,"value":4826},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":4828,"total":5003},[4829,4853,4869,4885,4899,4913,4927,4939,4951,4963,4979,4991],{"slug":4830,"name":4830,"fn":4831,"description":4832,"org":4833,"tags":4834,"stars":4850,"repoUrl":4851,"updatedAt":4852},"qdrant-horizontal-scaling","guide Qdrant horizontal scaling decisions","Diagnoses and guides Qdrant horizontal scaling decisions. Use when someone asks 'vertical or horizontal?', 'how many nodes?', 'how many shards?', 'how to add nodes', 'resharding', 'data doesn't fit', or 'need more capacity'. Also use when data growth outpaces current deployment.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4835,4838,4841,4844,4847],{"name":4836,"slug":4837,"type":15},"AI Infrastructure","ai-infrastructure",{"name":4839,"slug":4840,"type":15},"Architecture","architecture",{"name":4842,"slug":4843,"type":15},"Capacity Planning","capacity-planning",{"name":4845,"slug":4846,"type":15},"Database","database",{"name":4848,"slug":4849,"type":15},"Qdrant","qdrant",36978,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fawesome-copilot","2026-04-18T04:46:16.349561",{"slug":4854,"name":4854,"fn":4855,"description":4856,"org":4857,"tags":4858,"stars":4850,"repoUrl":4851,"updatedAt":4868},"qdrant-indexing-performance-optimization","optimize Qdrant indexing performance","Diagnoses and fixes slow Qdrant indexing and data ingestion. Use when someone reports 'uploads are slow', 'indexing takes forever', 'optimizer is stuck', 'HNSW build time too long', or 'data uploaded but search is bad'. Also use when optimizer status shows errors, segments won't merge, or indexing threshold questions arise.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4859,4862,4863,4866,4867],{"name":4860,"slug":4861,"type":15},"Data Engineering","data-engineering",{"name":4845,"slug":4846,"type":15},{"name":4864,"slug":4865,"type":15},"ETL","etl",{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},"2026-04-18T04:46:02.766357",{"slug":4870,"name":4870,"fn":4871,"description":4872,"org":4873,"tags":4874,"stars":4850,"repoUrl":4851,"updatedAt":4884},"qdrant-memory-usage-optimization","optimize Qdrant memory usage","Diagnoses and reduces Qdrant memory usage. Use when someone reports 'memory too high', 'RAM keeps growing', 'node crashed', 'out of memory', 'memory leak', or asks 'why is memory usage so high?', 'how to reduce RAM?'. Also use when memory doesn't match calculations, quantization didn't help, or nodes crash during recovery.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4875,4878,4879,4882,4883],{"name":4876,"slug":4877,"type":15},"Cost Optimization","cost-optimization",{"name":4845,"slug":4846,"type":15},{"name":4880,"slug":4881,"type":15},"Observability","observability",{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},"2026-04-18T04:46:01.525023",{"slug":4886,"name":4886,"fn":4887,"description":4888,"org":4889,"tags":4890,"stars":4850,"repoUrl":4851,"updatedAt":4898},"qdrant-minimize-latency","minimize Qdrant query latency","Guides Qdrant query latency optimization. Use when someone asks 'search is slow', 'how to reduce latency', 'p99 is too high', 'tail latency', 'single query too slow', 'how to make search faster', or 'latency spikes'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4891,4892,4893,4894,4895],{"name":4839,"slug":4840,"type":15},{"name":4845,"slug":4846,"type":15},{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4896,"slug":4897,"type":15},"Search","search","2026-04-18T04:46:10.126667",{"slug":4900,"name":4900,"fn":4901,"description":4902,"org":4903,"tags":4904,"stars":4850,"repoUrl":4851,"updatedAt":4912},"qdrant-monitoring-debugging","debug Qdrant production issues with metrics","Diagnoses Qdrant production issues using metrics and observability tools. Use when someone reports 'optimizer stuck', 'indexing too slow', 'memory too high', 'OOM crash', 'queries are slow', 'latency spike', or 'search was fast now it's slow'. Also use when performance degrades without obvious config changes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4905,4906,4909,4910,4911],{"name":20,"slug":21,"type":15},{"name":4907,"slug":4908,"type":15},"Monitoring","monitoring",{"name":4880,"slug":4881,"type":15},{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},"2026-04-18T04:46:06.450784",{"slug":4914,"name":4914,"fn":4915,"description":4916,"org":4917,"tags":4918,"stars":4850,"repoUrl":4851,"updatedAt":4926},"qdrant-monitoring-setup","set up Qdrant monitoring and alerting","Guides Qdrant monitoring setup including Prometheus scraping, health probes, Hybrid Cloud metrics, alerting, and log centralization. Use when someone asks 'how to set up monitoring', 'Prometheus config', 'Grafana dashboard', 'health check endpoints', 'how to scrape Hybrid Cloud', 'what alerts to set', 'how to centralize logs', or 'audit logging'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4919,4920,4921,4922,4923],{"name":4836,"slug":4837,"type":15},{"name":4907,"slug":4908,"type":15},{"name":4880,"slug":4881,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4924,"slug":4925,"type":15},"SRE","sre","2026-04-18T04:46:05.217192",{"slug":4928,"name":4928,"fn":4929,"description":4930,"org":4931,"tags":4932,"stars":4850,"repoUrl":4851,"updatedAt":4938},"qdrant-scaling-data-volume","scale Qdrant data volume","Guides Qdrant data volume scaling decisions. Use when someone asks 'data doesn't fit on one node', 'too much data', 'need more storage', 'vertical or horizontal scaling', 'tenant scaling', 'time window rotation', or 'data growth exceeds capacity'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4933,4934,4935,4936,4937],{"name":4836,"slug":4837,"type":15},{"name":4839,"slug":4840,"type":15},{"name":4842,"slug":4843,"type":15},{"name":4845,"slug":4846,"type":15},{"name":4848,"slug":4849,"type":15},"2026-04-18T04:46:07.684464",{"slug":4940,"name":4940,"fn":4941,"description":4942,"org":4943,"tags":4944,"stars":4850,"repoUrl":4851,"updatedAt":4950},"qdrant-scaling-qps","scale Qdrant query throughput","Guides Qdrant query throughput (QPS) scaling. Use when someone asks 'how to increase QPS', 'need more throughput', 'queries per second too low', 'batch search', 'read replicas', or 'how to handle more concurrent queries'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4945,4946,4947,4948,4949],{"name":4836,"slug":4837,"type":15},{"name":4839,"slug":4840,"type":15},{"name":4845,"slug":4846,"type":15},{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},"2026-04-18T04:46:08.905219",{"slug":4952,"name":4952,"fn":4953,"description":4954,"org":4955,"tags":4956,"stars":4850,"repoUrl":4851,"updatedAt":4962},"qdrant-scaling-query-volume","scale Qdrant query volume and pagination","Guides Qdrant query volume scaling. Use when someone asks 'query returns too many results', 'scroll performance', 'large limit values', 'paginating search results', 'fetching many vectors', or 'high cardinality results'.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4957,4958,4959,4960,4961],{"name":4839,"slug":4840,"type":15},{"name":4845,"slug":4846,"type":15},{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4896,"slug":4897,"type":15},"2026-04-18T04:46:11.371326",{"slug":4964,"name":4964,"fn":4965,"description":4966,"org":4967,"tags":4968,"stars":4850,"repoUrl":4851,"updatedAt":4978},"qdrant-search-quality-diagnosis","diagnose Qdrant search quality issues","Diagnoses Qdrant search quality issues. Use when someone reports 'results are bad', 'wrong results', 'not relevant results', 'missing matches', 'recall is low', 'approximate search worse than exact', 'which embedding model', or 'quality dropped after quantization'. Also use when search quality degrades without obvious changes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4969,4972,4975,4976,4977],{"name":4970,"slug":4971,"type":15},"Analytics","analytics",{"name":4973,"slug":4974,"type":15},"Data Quality","data-quality",{"name":20,"slug":21,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4896,"slug":4897,"type":15},"2026-04-18T04:46:17.579894",{"slug":4980,"name":4980,"fn":4981,"description":4982,"org":4983,"tags":4984,"stars":4850,"repoUrl":4851,"updatedAt":4990},"qdrant-search-speed-optimization","optimize Qdrant search speed","Diagnoses and fixes slow Qdrant search. Use when someone reports 'search is slow', 'high latency', 'queries take too long', 'low QPS', 'throughput too low', 'filtered search is slow', or 'search was fast but now it's slow'. Also use when search performance degrades after config changes or data growth.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4985,4986,4987,4988,4989],{"name":4970,"slug":4971,"type":15},{"name":4845,"slug":4846,"type":15},{"name":13,"slug":14,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4896,"slug":4897,"type":15},"2026-04-18T04:46:03.987332",{"slug":4992,"name":4992,"fn":4993,"description":4994,"org":4995,"tags":4996,"stars":4850,"repoUrl":4851,"updatedAt":5002},"qdrant-search-strategies","select optimal Qdrant search strategies","Guides Qdrant search strategy selection. Use when someone asks 'should I use hybrid search?', 'BM25 or sparse vectors?', 'how to rerank?', 'results are not relevant', 'I don't get needed results from my dataset but they're there', 'retrieval quality is not good enough', 'results too similar', 'need diversity', 'MMR', 'relevance feedback', 'recommendation API', 'discovery API', 'ColBERT reranking', or 'missing keyword matches'",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[4997,4998,4999,5000,5001],{"name":4836,"slug":4837,"type":15},{"name":4970,"slug":4971,"type":15},{"name":4839,"slug":4840,"type":15},{"name":4848,"slug":4849,"type":15},{"name":4896,"slug":4897,"type":15},"2026-04-18T04:46:18.812306",46,{"items":5005,"total":255},[5006,5012],{"slug":4,"name":4,"fn":5,"description":6,"org":5007,"tags":5008,"stars":22,"repoUrl":23,"updatedAt":24},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[5009,5010,5011],{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"name":13,"slug":14,"type":15},{"slug":5013,"name":5013,"fn":5014,"description":5015,"org":5016,"tags":5017,"stars":22,"repoUrl":23,"updatedAt":5029},"spark-app-template","build web applications with Spark templates","Comprehensive guidance for building web apps with opinionated defaults for tech stack, design system, and code standards. Use when user wants to create a new web application, dashboard, or interactive interface. Provides tech choices, styling guidance, project structure, and design philosophy to get users up and running quickly with a fully functional, beautiful web app.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[5018,5021,5024,5026],{"name":5019,"slug":5020,"type":15},"Design System","design-system",{"name":5022,"slug":5023,"type":15},"Frontend","frontend",{"name":1711,"slug":5025,"type":15},"templates",{"name":5027,"slug":5028,"type":15},"Web Development","web-development","2026-04-06T18:22:27.036934"]