Repository navigation
Conversation
Merging this PR will regress 2 benchmarks
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | take_fsl_u32_random[256, 10] |
124.4 µs | 158.5 µs | -21.51% |
| ❌ | WallTime | filtered_sink_i64_avx512[OneNullInEight] |
22.4 µs | 26.4 µs | -15.08% |
| ⚡ | Simulation | take_fsl_u32_random[16, 100] |
165.8 µs | 124.3 µs | +33.44% |
| ⚡ | Simulation | take_fsl_nullable_random[16, 100] |
187.6 µs | 163.8 µs | +14.54% |
| ⚡ | Simulation | take_fsl_f16_random[256, 100] |
231.8 µs | 203.1 µs | +14.13% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing myrrc/primitive-scalar-constructor (e6558ac) with develop (5c1671e)
Footnotes
-
293 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. ↩
Signed-off-by: Mikhail Kot <mikhail@spiraldb.com>
8963d51 to
e6558ac
Compare
|
This is a performance-neutral change, likely inlining didn't influence anything. Not worth merging |
Scalar's new()/try_new() runs validate() which checks for dtype/value
mismatches. This function may panic, so Rust generates landing pads and unwind
code which in turn may drop Scalar. Scalar is non-trivial so drop_glue is also
non-trivial, and the inlining cost for Scalar constructors is mostly due to
these pads.
For primitive and boolean Scalar, nullable or not, validate() is useless since
it doesn't have any primitive or bool specific checks, but you still pay the
cost of calling it when instantiating a Scalar. This in turn influences inlining
callers like
Array<Constant>::new::<u64>andArray<Constant>::new::<bool>.Fix this by using an unchecked constructor for primitive scalars.
We also have specialized constructors which create a Scalar from a value. They
construct dtype from the value itself and then pass to Scalar constructor which
validate() checks dtype and value coherence which will always be true by
definition. Construct Scalar unchecked for these values as well.
Second change in this PR is Mask::slice. By definition bounds of mask slice may
be incorrect only if underlying buffer lengths are incorrect, and we verify
these in constructors. If a user constructed a buffer without checks with
invalid length, all others checks don't apply as well since the contract is
broken. Change the asserts to debug asserts to make this function inlined