Skip to content

Conversation

@thevilledev
Copy link
Contributor

Motivation

Currently sum ranges like sum(1..100) and reduce(1..100, # + #acc) create a 100-element integer slice and iterate it element-by-element. When the range bounds are constant integers, this sum can be computed at compile time using the arithmetic series formula. This eliminates both the array allocation and iteration loop entirely.

Changes

Add a new optimizer pass sumRange that detects these patterns:

  • sum(m..n)
  • sum(m..n, #): identity predicate
  • sum(m..n, # * k) or sum(m..n, k * #): multiply each element
  • sum(m..n, # + k) or sum(m..n, k + #): add to each element
  • sum(m..n, # - k) or sum(m..n, k - #): subtract from each element
  • reduce(m..n, # + #acc) or reduce(m..n, #acc + #)
  • reduce(m..n, # + #acc, initialValue): with optional initial value

Patterns are optimized with a constant IntegerNode containing the result. The result is computed via the arithmetic series formula: (n - m + 1) * (m + n) / 2

Benchmark run for reduce:

go test -bench='Benchmark_reduce' -run=^$ -benchmem -count=10 .

Benchstat showing a decent return:

cpu: Apple M1 Pro
          │    old.txt    │               new.txt               │
          │    sec/op     │   sec/op     vs base                │
_reduce-8   5182.00n ± 3%   27.82n ± 1%  -99.46% (p=0.000 n=10)

          │   old.txt    │              new.txt               │
          │     B/op     │    B/op     vs base                │
_reduce-8   2448.00 ± 0%   32.00 ± 0%  -98.69% (p=0.000 n=10)

          │   old.txt    │              new.txt               │
          │  allocs/op   │ allocs/op   vs base                │
_reduce-8   183.000 ± 0%   1.000 ± 0%  -99.45% (p=0.000 n=10)

Further comments

The optimization only applies when n >= m. Reversed ranges like sum(10..1) are left unoptimized and handled by the runtime (returns 0 for sum, errors for reduce on empty array).

Optimize sum(m..n) and reduce(m..n, # + #acc) with constant integer
bounds to compile-time constants using the arithmetic series formula.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
@thevilledev thevilledev marked this pull request as ready for review January 5, 2026 20:08
@antonmedv antonmedv merged commit 0fcde75 into expr-lang:master Jan 5, 2026
18 checks passed
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.

2 participants