Skip to content

perf: Create IR slice from expr slice pushdown#27200

Draft
nameexhaustion wants to merge 4 commits intomainfrom
nxs/slice-pushdown-expr
Draft

perf: Create IR slice from expr slice pushdown#27200
nameexhaustion wants to merge 4 commits intomainfrom
nxs/slice-pushdown-expr

Conversation

@nameexhaustion
Copy link
Copy Markdown
Collaborator

@nameexhaustion nameexhaustion commented Apr 6, 2026

Create IR-level slices as the common slice of all expr slices that apply to columns. This can then be pushed down by the optimizer to perform the slice at lower levels.

In implementation, we add a new expr slice pushdown implementation via recursive tree traversal instead of going through OptimizationRule::optimize_expr, and this is called when doing IR slice pushdown on the exprs of each IR.

E.g. lf.select(pl.all().first()) can currently be much slower than lf.head(1), but after this PR it will optimize to the same as lf.head(1).

Detected exprs: head() / tail() / first() / last() / slice().

E.g. - The following now creates a slice at the scan:

print(pl.scan_csv(data).select(pl.first("a")).explain())
# SELECT [col("a").first()]
#   Csv SCAN [12 in-mem bytes]
#   PROJECT */1 COLUMNS
#   SLICE: Positive { offset: 0, len: 1 }
#   ESTIMATED ROWS: 6

E.g. - We are able to size the IR::Slice to the exact common boundary, then apply an offset correction to the expr slices -

print(
    pl.scan_csv(data)
    .select(a2=pl.col("a").slice(2, 1), a3=pl.col("a").slice(3, 1))
    .explain()
)
# SELECT [col("a").slice(offset=0, length=1).alias("a2"), col("a").slice(offset=1, length=1).alias("a3")]
#   Csv SCAN [12 in-mem bytes]
#   PROJECT */1 COLUMNS
#   SLICE: Positive { offset: 2, len: 2 }
#   ESTIMATED ROWS: 6

As well as for negative slices-

print(
    pl.scan_csv(data)
    .select(a2=pl.col("a").slice(-2, 1), a3=pl.col("a").slice(-3, 1))
    .explain()
)
# SELECT [col("a").slice(offset=-1, length=1).alias("a2"), col("a").slice(offset=-2, length=1).alias("a3")]
#   Csv SCAN [12 in-mem bytes]
#   PROJECT */1 COLUMNS
#   SLICE: Negative { offset_from_end: 3, len: 2 }
#   ESTIMATED ROWS: 6

--

@github-actions github-actions bot added performance Performance issues or improvements python Related to Python Polars rust Related to Rust Polars labels Apr 6, 2026
@nameexhaustion nameexhaustion changed the base branch from main to nxs/expr-projection-height April 6, 2026 19:31
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

The uncompressed lib size after this PR is 58.6537 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 0e6174f to 6750893 Compare April 6, 2026 23:33
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

The uncompressed lib size after this PR is 58.6615 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6620 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6692 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 5aff96b to 3b48dfd Compare April 7, 2026 02:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6603 MB.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 95.75758% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.91%. Comparing base (c492bc0) to head (24d289f).

Files with missing lines Patch % Lines
...rs-plan/src/plans/optimizer/slice_pushdown_expr.rs 96.09% 11 Missing ⚠️
crates/polars-utils/src/collection.rs 75.00% 3 Missing ⚠️
Additional details and impacted files
@@                       Coverage Diff                        @@
##           nxs/expr-projection-height-2   #27200      +/-   ##
================================================================
+ Coverage                         81.88%   81.91%   +0.03%     
================================================================
  Files                              1823     1824       +1     
  Lines                            251386   251618     +232     
  Branches                           3149     3149              
================================================================
+ Hits                             205842   206109     +267     
+ Misses                            44736    44701      -35     
  Partials                            808      808              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6682 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.4668 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6704 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6730 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6718 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

The uncompressed lib size after this PR is 58.6717 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The uncompressed lib size after this PR is 58.6603 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The uncompressed lib size after this PR is 58.6753 MB.

2 similar comments
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The uncompressed lib size after this PR is 58.6753 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The uncompressed lib size after this PR is 58.6753 MB.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 8, 2026

The uncompressed lib size after this PR is 58.6746 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/expr-projection-height branch from 72cee3c to a14cb00 Compare April 9, 2026 14:31
@nameexhaustion nameexhaustion changed the base branch from nxs/expr-projection-height to nxs/expr-projection-height-2 April 9, 2026 17:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

The uncompressed lib size after this PR is 58.6767 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 36d7d67 to 45467a9 Compare April 9, 2026 18:36
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

The uncompressed lib size after this PR is 58.8740 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 45467a9 to 5d7232c Compare April 10, 2026 11:56
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 58.8732 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 5d7232c to cee7313 Compare April 10, 2026 15:08
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 58.8688 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/expr-projection-height-2 branch from 2d26193 to c492bc0 Compare April 11, 2026 15:37
@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from cee7313 to 24d289f Compare April 11, 2026 15:40
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 58.6718 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/expr-projection-height-2 branch from c492bc0 to 352bd25 Compare April 14, 2026 09:11
@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 24d289f to ecf3a44 Compare April 14, 2026 09:11
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 61.4957 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/expr-projection-height-2 branch from 352bd25 to 7de45c2 Compare April 15, 2026 13:48
@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from ecf3a44 to ed4c2de Compare April 15, 2026 13:49
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 60.9760 MB.

@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch 3 times, most recently from fb915c3 to 31125ce Compare April 16, 2026 11:47
@nameexhaustion nameexhaustion force-pushed the nxs/expr-projection-height-2 branch from 028a364 to 56074cb Compare April 16, 2026 11:47
@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 31125ce to 9917f1d Compare April 16, 2026 11:48
@nameexhaustion nameexhaustion force-pushed the nxs/slice-pushdown-expr branch from 9917f1d to 1ef6b6a Compare April 16, 2026 11:51
@github-actions
Copy link
Copy Markdown
Contributor

The uncompressed lib size after this PR is 60.6818 MB.

Base automatically changed from nxs/expr-projection-height-2 to main April 16, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance issues or improvements python Related to Python Polars rust Related to Rust Polars

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Insert IR-level slice before select(all().head/tail(N)/first/last)

1 participant