Repository navigation
perf(linter): single-pass byte scan for L010 redundant whitespace [W6-04] - #902
Conversation
…-04] L010 rebuilt every non-quoted part of a line with a strings.Builder and ran the regexp ` +` over each part. It now scans the line's bytes once, tracking single and double quotes, and reports each run of two or more spaces that does not start the line (indentation). Violations are identical except on invalid UTF-8, where columns are now true byte positions (the old rune loop wrote U+FFFD, shifting columns). Tests: a differential test against the previous implementation (kept in a test file as the oracle) over 129 corpus files, 3,002 statements and 300,000 seeded random lines (30,000 under -race, 2.3 s); explicit tests for the invalid-UTF-8 column change. M4, GOGC=off -cpu 1, 10 interleaved rounds, LintRule/L010 per dialect: -70.3% to -74.6% (geomean -71.4%), B/op and allocs/op 0 (from ~100 KiB and ~2.5k). The real-world corpora have no L010 violations, so this measures clean input; the violation path appends a Violation as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ajitpratap0's task in 18s —— View job Review of PR #902: single-pass byte scan for L010Verdict: Looks good. I found no blocking issues. I read the diff but did not run the tests or benchmarks. This relies on your reported gate results. Correctness
Performance and design
Tests
SecurityNo concerns. The scan is a bounded O(n) loop with no allocation driven by input. ProcessThis is a draft until the W0-02 behaviour goldens and the W0-09 perf gate are on |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
Claude finished @ajitpratap0's task in 17s —— View job Review of PR #902: single-pass byte scan for L010Verdict: No blocking issues. I read the diff of Correctness
Performance and design
Tests
SecurityNo concerns. The scan is a bounded O(n) loop with no input-driven allocation. ProcessDraft status is sensible while W0-02 and W0-09 are pending. Re-run the behaviour goldens once they land, because the invalid-UTF-8 column change could show up there. |
Perf gate: PASS (shadow mode: report only, this check never fails)Base Runner CPU:
Rules: time regresses at >= +3% with p < 0.01 (Mann-Whitney U), or a suite geomean >= +1.5% (per-round geomeans, same test); allocs/op must not increase; B/op must not rise more than 2%; instructions/op must not rise more than 1.5%. An A/A control with more than 10% of benchmarks moving over 3% is noisy: re-run once, then inconclusive (neutral). Gated suite (GOGC=off, GOMAXPROCS=1)
A/A control: 0 of 50 benchmarks moved more than 3%. Instructions per operation (cmd/perfdriver)
Secondary metric: default GC, GOMAXPROCS=1 (informational)
Environmentbenchstat (primary metric) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
Claude finished @ajitpratap0's task in 15s —— View job Review of PR #902: single-pass byte scan for L010Verdict: No blocking issues. I read the diff of Correctness
Performance and design
Tests
SecurityNo concerns. The scan is a bounded O(n) loop with no input-driven allocation. ProcessThe W0-02 goldens now pass unchanged on the merged branch, which addresses my earlier concern about the invalid-UTF-8 column change showing up there. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
Claude finished @ajitpratap0's task in 21s —— View job Review of PR #902: single-pass byte scan for L010Verdict: No blocking issues. I read the current Correctness
Minor observations (non-blocking)
Performance
SecurityNo concerns. The scan is a bounded O(n) loop and does not allocate based on input. TestsThe differential test covers 129 corpus files, 3,002 statements and 300k random lines. The race/norace split keeps |
#896 (L007), #902 (L010) and #905 (lazy error wrap) target benchmarks the PR-run gate never measured, so none of them could be accepted or closed on an amd64 verdict. long_prefix is included so #905's expected miss is still checked for regressions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
…w suite (#927) * ci(perf): add BenchmarkLintRW to the shadow gate suite PR #906's gate run moved 0 of 26 benchmarks because no linter benchmark was gated. Add it so W6-05b, W6-06 and W6-07 are measured by the PR-run gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2 * ci(perf): gate LintRule L007/L010 and ParseError in the shadow suite #896 (L007), #902 (L010) and #905 (lazy error wrap) target benchmarks the PR-run gate never measured, so none of them could be accepted or closed on an amd64 verdict. long_prefix is included so #905's expected miss is still checked for regressions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2 --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Resolve CHANGELOG (and gate-suite) conflicts by placing this PR's entries in main's Unreleased sections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
Claude finished @ajitpratap0's task in 14s —— View job Review of PR #902: single-pass byte scan for L010Verdict: No blocking issues. I read the current Correctness
Non-blocking observations
Performance
SecurityNo concerns. The scan is a bounded O(n) loop with no input-driven allocation. TestsThe differential test covers 129 corpus files, 3,002 statements and 300k random lines. The race/norace split keeps |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
|
Claude finished @ajitpratap0's task in 20s —— View job Review of PR #902: single-pass byte scan for L010Verdict: No blocking issues. I read the current Correctness
Non-blocking observations
Performance
SecurityNo concerns. The scan is a bounded O(n) loop with no input-driven allocation. TestsThe differential test covers 129 corpus files, 3,002 statements and 300k random lines. The race/norace split keeps |
Summary
Wave-1 task W6-04 from the 2026-11 performance audit (LINT-3). The prototype was confirmed by an independent verifier. Codex ported it; Opus reviewed it and ran the full gate.
Before: for every line, L010 rebuilt each non-quoted part of the line with a
strings.Builderand ran the regexp+over each part.After: it scans the line's bytes once, tracking single and double quotes, and reports each run of two or more spaces that doesn't start the line. A run at the start of the line is indentation and is skipped, as before.
Edge cases: checked against the old code for indentation after tabs, runs after a closing quote, and unterminated strings. All behave the same.
One intended behaviour change, recorded in CHANGELOG: on lines with invalid UTF-8, columns are now true byte positions. The old rune loop wrote U+FFFD, which is 3 bytes, in place of each invalid byte, so columns drifted.
Merged with current
main(wave 0 is in). The W0-02 goldens pass unchanged (TestGoldenLintand the fulltask check); no golden cell changed. The package-local benchmark was dropped in favour of the wave-0 matrix benchmarkBenchmarkLintRule/L010inpkg/linter.Test Plan
Tests added:
testdata/realworld/*andtestdata/corpus/*, and 300,000 seeded random lines. Under-raceit runs a 30,000-line subset, which takes 2.3 s.Gate, run outside the Codex sandbox:
go run honnef.co/go/tools/cmd/staticcheck@latest ./pkg/linter/...go test -race -count=1 ./pkg/linter/...task checktask test:cbindinggo test -count=1 ./pkg/compatibility/...Local A/B (wave-0 matrix, indicative only; shared M4):
task bench:ab BASE=origin/main 'BENCH=./pkg/linter=^BenchmarkLintRule$/^L010$', 10 rounds, benchstat.Violationexactly as before.CI amd64 perf gate (shadow), run 41326073387: PASS. No gated metric moved past its threshold: gated-suite geomean +0.22% (within noise; A/A control 0 of 26 moved >3%), allocs/op unchanged and B/op +0.00% on every gated benchmark, instructions/op within +-0.5%. Note: the default gated suite (ParseE2E, ParseRW, ParseFresh, PoolGetPut, Tokenize) does not include
BenchmarkLintRule/L010, so the gate confirms no collateral regression but does not itself measure this task's target. The target gain is the local M4 number above (-67.7%, 0 allocs); an amd64 measurement ofLintRule/L010was not available from the gate.Breaking Changes
None to the API. The one behaviour change is the invalid-UTF-8 column numbers described in the summary.
Update after review (merge of origin/main 9d3d8b0)
### Performancesection.!inStringguard (commented) and added named edge-case column tests (tab then spaces, run after closing quote, unterminated quote, whitespace-only line).BenchmarkLintRule/L010cannot be measured on amd64 CI. Merge needs either a suite-extension PR (add./pkg/linter ^BenchmarkLintRule$/^L010$and^BenchmarkLintRW$) or an explicit orchestrator waiver; neither has been given yet.🤖 Generated with Claude Code
https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2