Skip to content

Find duplicate pattern variables in a set of the bound names - #9260

Draft
cknitt wants to merge 1 commit into
masterfrom
pattern-variables-perf
Draft

cknitt wants to merge 1 commit into
masterfrom
pattern-variables-perf

Conversation

@cknitt

@cknitt cknitt commented Nov 7, 2026

Copy link
Copy Markdown
Member

Part of #9256 (duplicate check of pattern variables).

Typecore.enter_variable compared each new variable with all variables of the pattern so far, and a let rec … and … group is one pattern. The bound names are now kept in a set next to the list. Both live in one value of the request state, so resetting the pattern, add_pattern_variables and the save and restore around or-patterns carry the set along without extra code.

Measured with bsc on linux-arm64, a let rec group of n bindings (allocations were already linear; this saves string comparisons):

Bindings Before After
4,000 514 ms 475 ms
8,000 1.14 s 0.97 s
16,000 2.69 s 1.96 s

New tests: multiply_bound_variable_let_rec (a duplicate in a let rec group), multiply_bound_variable_or_pattern (an or-pattern binding the same name on both sides is accepted, then a real duplicate is reported) and multiply_bound_variable_alias (Some(a) as a).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kbf3gK1dcjbe97yY1wRMgs

@github-actions

github-actions Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Changelog

💅 Polish

  • Speed up type checking of patterns that bind many variables, such as large let rec groups.

Semantic Diff

1 commit · Full page

Find duplicate pattern variables in a set of the bound names

4bae89d · cknitt + Claude · Nov 07, 2026, 10:07 UTC

Why

Each new pattern variable was compared with every variable the pattern had bound so far, and a let rec … and … group is one pattern, so n bindings cost O(n²) string comparisons: 16,000 bindings took 2.7 s. They now take 2.0 s.

The names are kept in a set next to the list of variables, in one value, so that resetting the pattern and the save and restore around or-patterns carry both.

@codecov

codecov Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.74%. Comparing base (bf35764) to head (4bae89d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9260      +/-   ##
==========================================
- Coverage   81.74%   81.74%   -0.01%     
==========================================
  Files         457      457              
  Lines       65713    65712       -1     
==========================================
- Hits        53715    53714       -1     
  Misses      11998    11998              
Files with missing lines Coverage Δ
compiler/ml/typecore.ml 89.11% <100.00%> (-0.01%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new

pkg-pr-new Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@9260

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@9260

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@9260

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@9260

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@9260

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@9260

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@9260

commit: 4bae89d

@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

Why:
    Each new pattern variable was compared with every variable the
    pattern had bound so far, and a `let rec … and …` group is one
    pattern, so n bindings cost O(n²) string comparisons: 16,000 bindings
    took 2.7 s. They now take 2.0 s.

The names are kept in a set next to the list of variables, in one value,
so that resetting the pattern and the save and restore around or-patterns
carry both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kbf3gK1dcjbe97yY1wRMgs
Signed-off-by: Christoph Knittel <ck@cca.io>
@cknitt
cknitt force-pushed the pattern-variables-perf branch from 7d5740b to 4bae89d Compare November 7, 2026 18:06
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

🎉 Compiler benchmarks

Allocated words

In total: 456,989,425 → 457,158,125 (+0.04%).

Benchmark Base Head Change
stress/LetRec.res 35,120,632 35,257,343 +0.39%

Instructions

In total: 10,226,962,259 → 10,126,222,706 (-0.99%).

🎉 Improvement: 1 benchmark executes more than 1% fewer instructions.

Benchmark Base Head Change
stress/LetRec.res 1,431,510,943 1,325,636,900 -7.40%
stress/ObjectFields.res 957,097,722 962,171,555 +0.53%

Pull request 4bae89d compared with base bf35764 in this run.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant