Re-slice the downcast view instead of re-validating it - #57
Merged
Conversation
Measures the cost of one `slice` call per encoding, including the case that motivates the next commit: non-nullable list items whose child array still carries a validity buffer, which `downcast` has to scan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`TypedArray::slice` sliced the arrow array and then re-ran `L::downcast`
on the result: for a nested type that recurses into the children, and
where a child carries a validity buffer it rescans that bitmap — work the
whole array had already been validated against, and which slicing cannot
invalidate (a slice reaches a subset of the rows).
`LogicalType::slice_typed` is the new hook: it returns the view of the
sliced rows, or `None` to fall back to `downcast`. The default is `None`,
so a hand-written `LogicalType` impl keeps compiling and keeps today's
behavior. Every encoding in the crate overrides it — the leaves slice
themselves; the offset-based composites (list, list-view, map,
dictionary, run) move the parent's window and share the child view;
fixed-size lists move the child window too, since arrow re-bases their
values on slice.
slice of List<i64>, item null buffer 1.82µs -> 42ns
slice of List<List<i64>> (100k rows) 85ns -> 60ns
slice of i64 (1M) 34ns -> 34ns
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related
TypedArraypublic #23What
TypedArray::slicesliced the arrow array and then re-ranL::downcaston the result. For a nested type that recurses into the children, and where a child carries a validity buffer it rescans that bitmap — work the whole array was already validated against, and which slicing cannot invalidate (a slice reaches a subset of the rows).LogicalType::slice_typed(typed, offset, length) -> Option<Self::Typed>is the new hook: the view of the sliced rows, orNoneto fall back todowncast. The default isNone, so a hand-writtenLogicalTypeimpl keeps compiling and keeps today's behavior — the hook is additive.Every encoding in the crate overrides it:
Option<L>, newtypes,As<T, Repr>List,LargeList,ListView,Map,Dictionary,RunFixedSizeListAnyList,AnyUtf8,AnyBinaryMeasured with the new
slicebench (first commit, so the before/after is reproducible):The last row is the case worth having: non-nullable items whose child array carries a validity buffer, so
downcastscans it on every slice.Testing
slice_agrees_with_a_full_downcastcross-checks the fast path againstTypedArray::try_new(array.as_arrow().slice(…))for 22 encodings, over five windows each (whole, prefix, suffix, one row, empty), and asserts that slicing an already-sliced array lands where slicing once does — the case that catches a fast path which restarts the window rather than composing it.cargo test --all-features,cargo clippy --all-targets --all-features -- -D warnings,cargo fmt --checkpass.Compatibility
Additive:
slice_typedhas a default, so externalLogicalTypeimpls are unaffected. No public signature changes.🤖 Generated with Claude Code