Skip to content

Execute lower and strpos inputs through execute_step - #11407

Merged
asubiotto merged 4 commits into
developfrom
alfonso/lower-execute-step
Nov 12, 2026
Merged

asubiotto merged 4 commits into
developfrom
alfonso/lower-execute-step

Conversation

@asubiotto

@asubiotto asubiotto commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Stacked on #11310. Until that merges, this PR shows only the last commit.

Lower and Strpos decode their inputs inside execute, in a nested executor. When the input is a slice or a mask over a run-end or chunked array, the function gets a canonical array and runs once per row, even when the encoding could have pushed it into its values. #11310 lets the executor retry parent-reduce rules once a child is rewritten, but only for functions that hand their inputs back to the executor through execute_step. This continues the execute_step migration from #11100 and #11154 for Lower and Strpos.

Changes

  • Lower::execute_step and Strpos::execute_step request their inputs with require_input!(args, i => AnyColumnar), as Like and Between do, then call execute.
  • Tests: lower's preserves_runs_and_dictionary gets a sliced case, and strpos gets preserves_runs_of_a_slice. Both check that a function over a sliced run-end input stays run-end encoded. Both fail without this change, and both fail without Try reduce_parent rules after execute_parent rewrites the current node #11310.

Checks:

  • cargo test -p vortex-array passes.
  • cargo clippy -p vortex-array --all-targets --all-features -- -D warnings passes.
  • cargo +nightly-2026-09-10 fmt -p vortex-array --check passes.

Benchmark numbers will follow. No existing benchmark covers scalar functions over sliced or masked encoded inputs.

This change was written with help from an AI coding agent and I haven't reviewed it yet.

robert3005 and others added 3 commits November 12, 2026 12:55
While a scalar function waits on the executor stack for an input, execution
can rewrite that input into an encoding whose parent-reduce rules now match.
The optimizer only saw the input as it was before execution, so those rules
never ran. A slice over a run-end array executes into the run-end array, but
`RunEndScalarFnRule` never pushed the suspended between into the run values,
so every row was decoded and compared.

After a child under a suspended parent is rewritten, put it back into the
parent and try its parent-reduce rules, session kernels first. A rewrite
replaces the parent; otherwise the child is detached again. Both are in place
when the parent is uniquely owned.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018SWbEuVduQbmfuXAPx4p46
Signed-off-by: Robert Kruszewski <[email protected]>
Lower and strpos decoded their input in a nested executor, so a slice or
mask over a run-end or chunked array reached them as a canonical array
and they ran once per row. Request the input with execute_step, as Like
and Between do, so the encoding can first push the function into its
values.

Signed-off-by: Alfonso Subiotto <[email protected]>
Co-authored-by: Amp <[email protected]>
@asubiotto
asubiotto marked this pull request as ready for review November 12, 2026 12:22
@asubiotto
asubiotto requested a review from robert3005 November 12, 2026 12:22
@asubiotto asubiotto added the changelog/performance A performance improvement label Nov 12, 2026
Base automatically changed from claude/happy-hypatia-of8g85 to develop November 12, 2026 12:27
@codspeed

codspeed Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 11.97%

2 warnings

⚠️ Walltime results may be unreliable

Some benchmarks used the Walltime instrument outside CodSpeed Macro Runners, which can make the results inconsistent.

Learn more about Macro Runners

See affected benchmarks

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚡ 3 improved benchmarks
✅ 1918 untouched benchmarks
⏩ 50 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Walltime add_constant_shapes_neon[(32768, ConstantPerRow)] 15.9 µs 14.1 µs +12.65%
⚡ Walltime add_constant_shapes_neon[(32768, PerRowConstant)] 15.8 µs 14.2 µs +11.82%
⚡ Walltime add_constant_shapes_neon[(32768, PerRowNullableConstant)] 16.7 µs 15 µs +11.44%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing alfonso/lower-execute-step (d2ddcf8) with develop (3f55648)

Open in CodSpeed

Footnotes

  1. 50 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@asubiotto
asubiotto merged commit 2428666 into develop Nov 12, 2026
69 checks passed
@asubiotto
asubiotto deleted the alfonso/lower-execute-step branch November 12, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/performance A performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants