Logo F# Compiler Guide

Performance-improvement review: evidence and rule contract

This is the source-to-rule contract for the reviewer. corpus.md fixes discovery to 2026-04-22 through 2026-09-22, with evidence cutoff 2026-09-22T09:28:34Z. validation.md distinguishes frozen RED expectations, preserved failures and actual final C6 acceptance. G1-G8 are eight ordered checks, not eight unconditional benchmark demands.

Attribution correction (sprint 10): the #20348/#20352 seeds came from orchestration, not an original-user attestation of authorship. The audit below uses the captured comment, enclosing review, replies, account/role, automation disclosures and pinned source instead. source-attributed identifies what a participant posted and in which role; it does not certify unaided human composition. A User account, an empty enclosing review, absence of a model marker, interactive replies or a matching code change alone supplies no such certificate. Conversely, uncertainty is not evidence of AI authorship, and no writing-style test or external attestation prerequisite is imposed. These conversations are usable as attributed feedback with the stated limits.

All twelve rules remain request-required, independently of source attribution. Archived C5 and its extract call PERF-08/09 human-derived + request-required; that historical label is not proof of composition. Sprint 11 aligns the candidate/integration wording with source attribution, without claiming unaided composition. Its sole subsequent decision-rule repair is PERF-05's instrumentation clause, prompted by an actual missed source-backed development concern; original expectations and failures remain in validation. #20416's explicit AI disclosure applies to that review and attached inline findings. In contrast, #20261's review has no explicit automation disclosure in the captured review/comment envelopes: the earlier "model-associated" label is unsupported, so composition remains uncertain, not classified by style. Both remain excluded from verified-human votes, alongside bots, uncertain quotations, existing agents and synthetic cases. Author measurements are not independent review; code corroborates mechanisms/resolutions, not authorship.

Named conversation audit

Original REST bodies and GraphQL thread envelopes are in session c8f75c7a-5c38-4380-a60f-80b1f04b4d69\files (#19995/#20287/#20296/#20352) and 28a5997c-c817-48a9-8f00-4a45e40edbf0\files (#20348/#20353), under the archive root in validation.md. All named exchanges predate the cutoff. Their enclosing reviews contain no automation disclosure; #20352 and the elapsed-time exchange are general comments with no enclosing review or commit binding. This is a bounded envelope finding, not certainty about composition. Release-note bots and empty approvals are not supporting feedback.

Source / participant role and envelope

Concern, pinned revision and resolution/counterexample

Narrow mapping to existing rules

#20353: auduchinok, MEMBER reviewer elapsed-time question; T-Gro, MEMBER author answer. Source-attributed conversation; no enclosing review.

Commit-unbound question/answer; final context 604669d1a6fd688f6ee0cd1daff3e7020192a080. Author reports 477 MB -> 0 allocation, says time is noisy and quotes a 99.75% hit ratio. Neither the asserted time direction nor hit ratio quantifies elapsed benefit.

PERF-03/04: select evidence for the actual claim; an allocation win need not prove a timing win. One-off timing question, not a human mandate for every metric or a rejection.

#20287: T-Gro, MEMBER reviewer reader concern, enclosing review 4970838372; self-qualification; auduchinok, MEMBER author answer, review 4970925639.

Original 63df5b0fb83a5439dcad47672c01df9b6ad6fe57, not remapped final 9252af630067c59e8fd087380a5d52ecd95c15a6. Reviewer asks about releasing a closure, then questions the saving because readers are shared; author confirms no saving. Original/final source retains the shared reader.

PERF-05/12: trace ownership before demanding release; withdraw a concern when its premise fails. This does not establish a leak or "always clear readers."

#20296: T-Gro, MEMBER reviewer typed-key request, review 5007592882; shared-settings request, review 5007678895.

Original 09a3cb1dbc832f9e2d4e8711e4726f9043eb91c0: opaque strings and duplicated reuse-relevant flags. Final 86ece46d9e5a7ae67aca866749ae4f377dab5ff1 adds SharedCcuKey and ImportReuseKey, used by framework/service sharing checks. No direct reply to these two requests; resolution is source-backed, not inferred from approval. The default-setting reply answers a different thread.

PERF-06/09/10: make cache identity reviewable and reuse the relevant settings definition; inspect hit/miss/error behavior. The reviewer's recollection of past missing flags is not a new reproduced defect. One-off concrete typed-key request, not mandatory abstraction for every cache.

#19995: majocha, CONTRIBUTOR reviewer instrumentation cost, review 4578821416; T-Gro, MEMBER reviewer narrower instrumentation gate; NatElkins, CONTRIBUTOR author ownership/removal answer.

Original f96b70e1c112af68b5e14fd75fca4bc6ca7308c2; final bd2148ba7aff3a9f365be52a4e4769a56fef8acf removes per-cache listeners/IDs and uses disposable ListenToAll, name totals and documented serialized tests. At 1c1f7a9f7a222f823f1659234bfa49921d81427d, majocha suggests lightweight per-instance Stats, then accepts either design, review 4642793675. Author keeps aggregation.

PERF-03/05/10/11: include instrumentation cost/ownership and interference in measurement reasoning, prefer a simpler bounded mechanism, and retain accepted alternatives. No measured exporter slowdown or universal DEBUG gate is established.

#20348: brianrourkeboll, CONTRIBUTOR reviewer suggestion, review 5021077157; T-Gro, MEMBER author acceptance, review 5028138073.

Original 2a9e33aef0bf3df3bab894b332e8f0b55d7d9e08; final 95479116c5693f9b96727cc2ac88e965982e621e adopts comprehensions. The suggestion says "approximately as fast" tentatively; acceptance says nicer, not measured faster.

PERF-09: consider a simpler idiom without inventing measured equivalence, syntax risk or a timing prerequisite for an unclaimed comparison.

#20352: T-Gro, MEMBER author withdrawal. No submitted reviews, inline discussion or enclosing review.

Commit-unbound rationale: too bloated for the win; sole submitted head 39167b8148d900fe003aea4cd80f95643fdb691f. #20363 is its narrower same-family continuation, not an independent reviewer vote.

PERF-08: weigh gain against common-mechanism complexity and ask for a narrower alternative or justification. Author withdrawal is not maintainer rejection or proof its allocation report was false.

Recurrence and limits: ownership-sensitive reasoning recurs across FAMILY-il-import-retention (#20287) and FAMILY-cache-listener (#19995), with opposite remedies because ownership differs. Reviewability/simpler alternatives recur across those families and FAMILY-self-profile (#20348); FAMILY-inline-copy (#20352) adds author rationale, not independent review. #20287/#20296 are one family, as are #20348/#20353. This is recurrence of attributed concerns, not a count of verified-human votes or consensus on one implementation. The #20353 time question, #20296 typed-key request and #20352 withdrawal remain one-off specific observations. The accepted cold-allocation trade-off remains attribution-limited contrary context, not another vote. No source supplies a universal significance threshold, peak-memory protocol or thread-pool benchmark mandate; the explicit conditional requirements below remain binding.

1. Need/value and target workload

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-01

Request contract: explain why this cost matters, to whom, and where it occurs.

Request origin; no human precedent claimed.

request-required

Not a historical review.

Tie the claim to a named compiler/FCS/IDE or generated-program workload and its hot path.

Concise why-focused description, profile or frequency evidence, input size/shape, baseline cost and expected user value.

Do not treat a microbenchmark as whole-build or user-latency evidence. Docs-only/no performance claim: metric checks not applicable.

2. PR description quality and tabular benchmark evidence

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-02

Request contract: make a quantitative claim falsifiable rather than prose-only.

Request origin. #20261's description is input context, not independent review evidence.

request-required; auduchinok's description is author-reported measurement, text origin uncertain.

Final code 9d8662d93106e401d67e480e5fb0d812b04cb57c; captured description has a retained-memory table and three fresh-process runs, but no published dispersion/environment/command.

Require a before/after table for the applicable measured claim; identify what the reported numbers do and do not establish.

Baseline/changed commits and configuration; units, workload/input size, repetitions, meaningful variability/error, hardware/OS/runtime/SDK/tool versions, reproducible commands and input/result links.

Do not ask for a table or repetitions already present. A current description cannot establish what was available at an earlier review. Missing metadata means needs evidence, not fabricated wrong numbers.

3. Metric selection and measurement validity

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-03

Request contract: select metrics for the claim; do not equate allocations, retained memory and elapsed time.

Context only: #20353 question, answer.

request-required; auduchinok reviewer question versus T-Gro author explanation; prose authorship unverified, not human-derived.

General comments are commit-unbound. Final 604669d1a6fd688f6ee0cd1daff3e7020192a080; author bounds reliable win to allocations and acknowledges noisy time; no quantified timing resolution.

An allocation-only improvement need not lower elapsed time; a speed claim needs time evidence. Check comparable inputs/configurations and confounders.

Appropriate counters, full workload selection, cold/warm state, warmup, cache policy, GC/timing boundaries and separate-process/repeated-run methodology as relevant.

Hit ratio, closure/IL counts or sampled CPU alone do not prove end-to-end speed. No fixed benchmark matrix. See metric mapping below.

4. Size/significance of the improvement

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-04

Request contract: distinguish a useful effect from noise or selective reporting.

Request origin; #20261 explicitly calls time changes noise-level, not a measured speed win.

request-required

No human significance threshold recovered.

Compare absolute and relative effects against observed variability and workload value, including regressions and unchanged cases.

Repeated comparable runs, spread/error definition, raw distributions or linked results, excluded-run rationale, all selected workloads and input revisions.

No arbitrary minimum percentage. Do not cherry-pick the best run, compare changed inputs as a code effect, or demand speed improvement for a narrowly supported allocation claim.

5. Regressions and resource trade-offs

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-05

Request contract: a good headline metric must not conceal a relevant resource/lifetime regression.

Request origin; #19995 remaining tag cost, instrumentation gate, and accepted alternative. #20261's bucket comparison is author measurement context.

request-required; #19995 source-attributed majocha/T-Gro reviewer concerns, composition limits above

Original f96b70e1c112af68b5e14fd75fca4bc6ca7308c2 retains tags/direct counters; final bd2148ba7aff3a9f365be52a4e4769a56fef8acf removes per-instance tags and reuses opt-in aggregation.

Follow resources introduced or prolonged by the optimization; raise risk/blocker only for a concrete mechanism, observed regression or substantiated failure scenario. For instrumentation changes, credit repaired ownership separately from remaining per-instance tags/filtering, direct counters and active-exporter costs.

When implicated: total allocated bytes and GC; live/retained/peak memory with lifetime boundaries; repeated/incremental work and release/eviction proof; CPU, thread counts, contention, thread-pool pressure, cancellation, starvation/hangs under realistic concurrency. For changed instrumentation, relevant enabled/disabled cost evidence or justification for a simpler bounded mechanism.

Allocated volume is not live memory or leak proof. A cache is not inherently a leak, and a weak reference alone is not lifetime proof. Missing relevant measurements means needs evidence. Useful diagnostics need not be removed or gated by a particular directive; the source does not establish a measured exporter slowdown.

6. Behavior/API/compatibility preservation

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-06

Request contract: removing work must not remove observable behavior.

Context only: #20353 range question, author answer.

request-required; abonie reviewer / T-Gro author; unverified text origin, not human-derived.

Original b77c6c6828547768dcdfed1a04347331fdd12e5c, final 604669d1a6fd688f6ee0cd1daff3e7020192a080; resolved discussion, no diagnostic-range regression test added. Author allows first-call attribution for malformed-metadata import errors.

Select behavior proof from the mechanism: semantics, diagnostics/ranges, APIs and binary/source compatibility, exceptions and cancellation, edge cases, ordering/determinism, and expected generated output.

Differential or targeted assertions on affected observable behavior, including relevant unusual inputs. Trace dropped cache-key inputs through misses/hits and error paths.

An unchanged signature is not behavior proof. Deliberately changed code generation needs expected-output/semantic proof, not universal byte-for-byte IL identity. An author explanation does not prove every diagnostic path equivalent.

PERF-07

Request contract: an optimization relying on an invariant needs evidence at its source.

Context only: #20349 request, resolution.

request-required; abonie reviewer / T-Gro author; unverified text origin, not human-derived.

Original b0770fe05ee57d56bbb292277cc35f20b3ec81f7; comment and debug assertion added in d33b15c5ef845d987bc5ad18f728f586892323d8, retained at cc98f598d445d5f5c1a2bf962ebd3d82fc599c5c; resolved.

For sort removal/order-dependent shortcuts, inspect producer order, ties, empty/singleton cases and consumers; preserve determinism.

Source invariant and an appropriate comment, assertion or test; explain equivalent ordering.

The source asked for comment or assertion, not both universally. Stop reporting the missing-invariant-documentation concern after it is addressed; assertions are not proof all executions passed.

7. Surgical scope, isolation, and implementation risk

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-08

Author withdrew a broad copy/remark fusion as too bloated for its win and planned a minimal rework.

#20352 withdrawal.

request-required; source-attributed T-Gro author rationale, composition unverified, not maintainer rejection.

Comment is commit-unbound; sole submitted head 39167b8148d900fe003aea4cd80f95643fdb691f, 427-line diff across optimizer/remapper/signature. Closed-unmerged; #20363 is the same family, not a second vote.

Weigh maintenance and review cost against demonstrated value when an optimization spreads through a common mechanism; request a narrower alternative or justification.

Allocation/time benefit on the target workload, proof of affected ranges/debug points/quotations, and comparison with helper reuse or a localized approach.

One PR/family supports this observation; no line-count cutoff, automatic rejection of large changes, or claim the reported 321 MB saving was false.

PERF-09

Reviewer tentatively suggested approximately-as-fast array comprehensions; author accepted their simpler form.

#20348 suggestion, acceptance.

request-required; source-attributed brianrourkeboll reviewer / T-Gro author exchange; composition unverified.

Original 2a9e33aef0bf3df3bab894b332e8f0b55d7d9e08; final 95479116c5693f9b96727cc2ac88e965982e621e adopts comprehensions. Resolved/outdated.

Where a lower-level rewrite adds complexity, consider a simpler existing idiom with equivalent behavior; measure any claimed performance difference.

Relevant generated code or focused comparison, retaining sort stability/key limits and workload.

One PR/family. Neither participant supplied measured equivalence in this thread; never infer comprehensions are always faster or make this a blocker based on syntax.

PERF-10

Request contract: isolate the cause of the improvement and reuse existing helpers.

Request origin.

request-required

No human recurrence claimed.

Separate independent optimizations, unrelated cleanup and behavior changes enough to attribute gains and review risk; prefer existing lifetime/collection/remapping helpers.

Per-mechanism evidence or controlled on/off comparison when a bundle obscures attribution; explain new abstraction/state and maintenance cost.

No blanket one-file/one-hunk rule. Small diffs can be unsafe; large changes can be justified.

8. Reproducibility, tests, and final recommendation

Rule ID

Concern and concise human paraphrase

Source PR and exact review/comment URL

Source kind and author/role

Reviewed revision and resolution

Resulting conditional reviewer rule

Evidence to request

Applicability/limits

PERF-11

Request contract: the test must exercise the property the optimization could change.

Context only: #20353 runtime-test request, answer.

request-required; abonie reviewer / T-Gro author; text origin unverified, not human-derived.

Original b77c6c6828547768dcdfed1a04347331fdd12e5c only compiled; 05406570004daef8ddc03603ca6425a3b0311a4e switched to compileExeAndRun, retained at final 604669d1a6fd688f6ee0cd1daff3e7020192a080; resolved.

Require executable assertions for runtime behavior, generated-output assertions for structural claims, and repeated/incremental tests for stateful optimizations when relevant.

Targeted tests/results and reproducible benchmark command/input/compiler provenance; actual compiler path/version, not merely a successful build.

Compile-only success cannot prove a runtime conditional. Recognize the final test executes it; do not invent a test failure or claim it ran during this sprint.

PERF-12

Request contract: separate missing proof, demonstrated risk and inapplicability in the recommendation.

Request origin; exact outcomes in validation.md.

request-required

RED expectations and C5 execution records are distinct; model replay is not a human-source audit.

Give each of G1-G8 an applicable outcome with evidence; final recommendation reflects unresolved material risks and specifically missing evidence.

Exact source/code/measurement supporting each conclusion; concise outstanding evidence requests.

pass is local to a supported check, not certification. needs evidence is not a defect. risk/blocker needs a concrete mechanism/evidence. not applicable needs a reason. Neither approval/merge nor closure substitutes for assessment.

Conditional metric mapping

Choose the primary measurement from the actual claim and investigate only implicated trade-offs. Do not require all rows for every PR.

Claim/workload

Primary measurement

Related trade-off to test when relevant

Human source IDs or request origin

Faster operation, IDE response or service

Elapsed time/latency distribution or throughput with workload/concurrency and units

Tail latency, CPU, allocation/GC, warmup/caches, sustained versus isolated work

Request: PERF-01/03/04/05

Less memory across a compile/solution

Define total process/heap footprint, retained live bytes at a stated lifecycle point, or peak over the interval

Total allocated bytes, GC, duplicate objects, post-close/repeated/incremental retention

Request: PERF-03/05; #20261 author table is context, not a human vote

Fewer allocations

Allocation count/allocated bytes per operation or compile

GC collections/pause time, relevant elapsed-time or retention regression

Request: PERF-03/05; #20353 question/answer remain attribution-limited

Less GC work

Collection counts/generations and pause/time under a defined load

Allocation volume, retained/peak heap, throughput and latency

Request: PERF-05

Fewer closures or generated artifacts

Before/after closure/type/method/IL counts with compiler flags and expected output

Runtime allocation/size; semantics and runtime speed only if claimed

Request: PERF-03/06/11; counts do not prove end-to-end speed

Less CPU work

CPU time or correctly defined sampled/exclusive/inclusive profile

Elapsed time, parallel work, contention, total workload completion

Request: PERF-03/05

Better concurrency/parallelism

Throughput/latency at named concurrency; active threads/work items and CPU

Thread-pool pressure, starvation/hangs, contention, cancellation, memory and determinism

Request: PERF-05/06

Faster startup/build/compiler/FCS

Cold startup/build elapsed time or named parse/check operation; incremental/warm work separately

Peak/retained memory, allocations, cache hits/reuse and repeated builds/checks

Request: PERF-01/03/05

Workload-specific bottleneck

Relevant measure such as emitted bytes, metadata rows, cache hit/miss/eviction counts or processed inputs/second

End-to-end relevance and affected behavior/resource cost

Request: PERF-01/03; PERF-08/09 add source-attributed scope observations, not metric mandates

Tooling context, not human evidence

Post-C3 evaluation correction (request-required, not new human training history): HOLD-09's frozen oracle required a modern-runtime comparison with hardware intrinsics disabled. C3 asked about .NET Framework and broader inputs but missed that condition. The final source chooses LINQ on modern runtimes and the old loop on Framework; Framework data therefore does not measure LINQ's modern scalar fallback. The earlier request is attribution-limited 2025 context, not a newly verified human precedent or in-window human vote. PERF-03 now explicitly asks for representative supported fast/fallback paths on the same runtime when capability-dependent dispatch is implicated. This is not a universal hardware/OS/runtime benchmark matrix. The original C3 output/oracle remain in validation.md; #18509 becomes development, and a coached replay cannot count as independent holdout success.

Post-C4 development-regression correction (request-required): C4 recognized HOLD-01's changed runtime array type but treated its compatibility obligation as an unspecified policy, omitting the concrete formerly successful downcast that now fails. This exposed development case was already excluded from holdout credit. PERF-06/12 distinguish representation differences requiring investigation from source-established caller failures, which are material risk even without a separate policy document. Intentional empty sharing does not automatically authorize the collateral runtime-type break. C5 makes that classification explicit; no new human precedent or changed oracle is claimed.

At checkout ae294143e5890033fcb717956050a91a6f2ed6e8, benchmark guidance distinguishes compiler/service work from generated-program runtime and cautions about environment differences. Historical FCS comparison measures FSharpChecker.ParseAndCheckFileInProject; its per-version BenchmarkDotNet processes and API compatibility defines need recording. A ParseAndCheckProject retention claim is not automatically covered by that single-file benchmark.

Compiled-program benchmarks use tests\benchmarks\CompiledCodeBenchmarks\MicroPerf\MicroPerf.fsproj. Program.fs configures Current as baseline and Preview as a custom build configuration; the project selects preview language/local compiler for that configuration. These labels are not baseline/PR commit identities. Verify the binaries, runtime, flags and compiler versions actually used on both sides.

When appropriate, BuildWithLocalFSharp.fsx supplies local compiler/core overrides after a Release packed build; its --verify mode checks the resolved FSharp.Core version in assets files, not the compiler binary's identity. Retain the actual compiler path/version separately. This is tooling choice, not a mandatory matrix or a benchmark result. The existing expert-reviewer remains responsible for broad compiler review; these rules request behavior proof only where a performance mechanism could change it.

Type something to start searching.