Repository navigation
perf(ast): ASCII fast path in identifierNeedsQuoting, hash-free isReservedName [W5-04] - #945
ajitpratap0 wants to merge 5 commits into
Conversation
…ervedName [W5-04] Byte-class table for ASCII names (rune loop only for non-ASCII), and a first-letter/length index derived from reservedNameWords replaces the map lookup. SQL() output is byte-identical. 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 22s —— View job Review of PR #945 (ASCII fast path for identifier quoting)I read the diff and traced the logic by hand. I did not run the tests or benchmarks. The sandbox blocked the Verdict: Looks correct. I found no blocking issues.
Minor nits (non-blocking)
Tests
Performance and security
|
…ut [W5-04] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
Perf gate: PASS (shadow mode: report only, this check never fails)Base Runner CPU:
Rules: each arm runs 20 randomized code layouts ( Gated suite (GOGC=off, GOMAXPROCS=1)
A/A' control (base revision, disjoint layout seeds): 0 of 52 benchmarks moved more than 3%; 0 would have been flagged by the time rule; suite geomean -0.13%, p 0.758. Low power1 benchmark(s) have under 80% estimated power to be flagged on their own for a +5% slowdown (their spread across layouts is too wide for 20 layouts at the Benjamini-Hochberg level alpha/m = 0.000192). A slowdown below the last column usually goes unflagged there; instructions/op, allocs/op and the suite geomean still guard them.
Power is estimated with the normal approximation for the U test (Noether): power = Phi(ln(1+shift)/s * sqrt(K/2) * sqrt(3/pi) - z(1 - alpha/(2m))), with s the spread and K the layouts per arm. Instructions per operation (cmd/perfdriver)
Secondary metric: default GC, GOMAXPROCS=1 (informational)
Environmentbenchstat (primary metric, samples pooled across layouts: informational, the verdict uses the per-layout test) |
|
Claude finished @ajitpratap0's task in 18s —— View job Review of PR #945 (ASCII fast path for identifier quoting)I read the diff against Verdict: Looks correct. I found no blocking issues.
Remaining nits (non-blocking)
Tests
Performance and security
|
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 #945 (ASCII fast path for identifier quoting)I read the diff against Verdict: Looks correct. I found no blocking issues.
Nits (non-blocking)
Tests
Performance and security
|
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 #945 (ASCII fast path for identifier quoting)I read the diff against Verdict: Looks correct. I found no blocking issues.
Nits (non-blocking)
CHANGELOG
Tests
Performance and security
|
Summary
identifierNeedsQuoting: 256-entry byte-class table for ASCII names; the first non-ASCII byte falls back to the unchanged rune loop (identifierNeedsQuotingRunes).isReservedName: first-letter/length index of[16]byteentries derived at init fromreservedNameWords(which stays the single word list), array-compare scan, zero allocations. This deviates from the PLAN label "switch-based": a generated index keeps one source of truth at the same speed.AST.SQL()and formatter output byte-identical.Test Plan
pkg/sql/ast/quote_fastpath_test.go: frozen reference copies, exhaustive 0-2 byte and piece-combination equivalence, reserved-name case/affix/exhaustive 3-byte equivalence, index invariants,FuzzQuoteFastPath(60s, 944k execs, clean), zero-alloc pins, micro benchmarks.TestIdentifierNeedsQuoting_MatchesReference; M4TestIdentifierByteClass_NonASCII; M5, M7TestIsReservedName_MatchesReference; M6TestReservedNameIndex_Invariants+TestIsReservedName_MatchesReference.task goldensclean, no golden changes.task check(after merging origin/main),task test:cbinding,go test ./pkg/compatibility/..., staticcheck onpkg/sql/ast/..., targeted-racerun: all pass.task bench:ab, Apple M4, shared machine, indicative only; spread up to +/-223%):BenchmarkRendergeomean -9.78%; sql/select_where -17%, sql/join -15%, sql/cte -21%, readable/delete -9.7%; sql/complex and sql/insert no change.Intel(R) Xeon(R) 6975P-C): PASS. No time regression; allocs/op and B/op unchanged on every gated benchmark; instructions/op between -7.34% (e2e/cte) and +0.06% (e2e/simple_select),e2e/complex-4.32%; A/A' control clean (0 of 52 benchmarks moved more than 3%, suite geomean -0.08%, p 0.369). Low power list (9):ParseError/long_prefix/validate,ParseE2E/delete,LintRule/L010,ParseE2E/simple_select,ParseRW/clickhouse/medium,ParseRW/snowflake/medium,Tokenize/scratch/insert,Tokenize/scratch/complex,LintRW/oracle; none is in this change's blast radius, and allocs/op, B/op and instructions/op guard them.BenchmarkNormalize(renders through the same helpers): simple_select -2.85%, join -2.35% (both p<0.001, status ok), complex -4.94% (p<0.001, flagged 'faster'); allocs/op and B/op unchanged. Under PLAN 5.3 rule 5 this is the amd64 evidence of a real gain, so the PR is not closed.Normalizeagain significant and faster: simple_select -1.82%, join -2.27%, complex -3.32% (p<0.001, A/A' -0.85%..-0.47%), allocs/op and B/op unchanged.pkg/formatter BenchmarkRender(not in gate-suite.txt), via the layout-randomized matrix route (perf-gate.yml -f mode=matrix -f rounds=20 -f layouts=20, run 41706707217, AMD EPYC 9V74, GOGC=off, pinned CPU). The job hit the 230-minute limit before the A/A' stage and the report step, so its report is ERROR; I ranscripts/perf/gateon the 16 completed layouts per arm of the raw gcoff files instead (no A/A' control for this run). The base of that run (6d29d68) carried the L007 keyword_case change that this branch lacked, so ignore its Lint rows; Render rows are unaffected. Render/sql: simple_select -10.96%, select_where -17.56%, join -14.77%, aggregate -14.35%, subquery -15.16%, cte -19.89%, window -18.57%, complex -17.31%, insert -10.70%, update -13.08%, delete -12.78% (all p<0.001, allocs 1 -> 1, B/op +0.00%). Render/readable: simple_select -7.65%, select_where -10.98%, join -8.23%, aggregate -9.80%, subquery -8.63%, cte -9.17%, window -8.14%, complex -9.01%, insert -7.95%, update -5.72%, delete -7.57% (all p<0.001, allocs/op and B/op unchanged). Targets met: render/sql <= -7% (worst row -10.70%) and render/readable <= -3% (worst row -5.72%).isReservedName(one word list stays the source of truth).Breaking Changes
None.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2