Commit 284ae30
Perf: cache primitive sort key in SortPreservingMerge to drop per-comparison bounds checks (#23162)
## Which issue does this PR close?
<!-- No dedicated issue; this is a self-contained performance
improvement to the
sort-preserving merge hot path. Happy to file a tracking issue if
preferred. -->
- N/A (performance)
## Rationale for this change
Two inefficiencies in the hot path:
1. The single-column primitive/array cursor comparison was **not being
inlined**
(in profiles it appeared as a separate ~21% self-time symbol), and every
comparison
bounds-checked the underlying `ScalarBuffer` twice.
2. `maybe_poll_stream` was called on **every** output row, even though
it is a
no-op whenever the winner's cursor is still live (the common case).
```
┏━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query ┃ HEAD ┃ perf_spm-compare-cache ┃ Change ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ Q1 │ 165.13 / 166.08 ±0.75 / 166.98 ms │ 131.46 / 132.49 ±0.79 / 133.86 ms │ +1.25x faster │
│ Q2 │ 141.22 / 141.86 ±0.81 / 143.38 ms │ 118.06 / 120.08 ±1.30 / 121.91 ms │ +1.18x faster │
│ Q3 │ 652.56 / 657.09 ±2.91 / 661.10 ms │ 645.82 / 649.88 ±3.27 / 654.55 ms │ no change │
│ Q4 │ 195.87 / 199.80 ±6.83 / 213.43 ms │ 180.22 / 183.86 ±5.04 / 193.43 ms │ +1.09x faster │
│ Q5 │ 279.14 / 279.91 ±0.50 / 280.71 ms │ 260.15 / 260.70 ±0.48 / 261.54 ms │ +1.07x faster │
│ Q6 │ 292.50 / 293.43 ±0.71 / 294.56 ms │ 273.28 / 274.77 ±1.66 / 277.81 ms │ +1.07x faster │
│ Q7 │ 465.87 / 467.23 ±2.01 / 471.21 ms │ 445.83 / 449.21 ±3.47 / 455.33 ms │ no change │
│ Q8 │ 327.51 / 330.08 ±3.25 / 336.40 ms │ 319.12 / 325.35 ±6.20 / 336.30 ms │ no change │
│ Q9 │ 342.17 / 346.17 ±2.68 / 348.71 ms │ 336.40 / 348.61 ±13.37 / 368.15 ms │ no change │
│ Q10 │ 484.08 / 486.50 ±2.53 / 490.75 ms │ 474.15 / 490.16 ±13.58 / 507.56 ms │ no change │
│ Q11 │ 244.24 / 250.98 ±8.70 / 267.17 ms │ 229.07 / 237.38 ±8.10 / 249.40 ms │ +1.06x faster │
└───────┴───────────────────────────────────┴────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary ┃ ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD) │ 3619.13ms │
│ Total Time (perf_spm-compare-cache) │ 3472.49ms │
│ Average Time (HEAD) │ 329.01ms │
│ Average Time (perf_spm-compare-cache) │ 315.68ms │
│ Queries Faster │ 6 │
│ Queries Slower │ 0 │
│ Queries with No Change │ 5 │
│ Queries with Failure │ 0 │
└───────────────────────────────────────┴───────────┘
```
## What changes are included in this PR?
- Inline the lightweight primitive/array cursor comparisons.
- Skip the per-row `maybe_poll_stream` call unless the winner's cursor
is
actually exhausted and needs a fresh `RecordBatch`.
- Cache the current (and previous) value of a primitive cursor,
refreshed once
per `advance()` via a new `CursorValues::set_offset` hook (default
no-op;
`ArrayValues` forwards to the inner cursor).
## Are these changes tested?
Existing tests
## Are there any user-facing changes?
No.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>1 parent a00f749 commit 284ae30
2 files changed
Lines changed: 104 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
47 | 55 | | |
48 | 56 | | |
49 | 57 | | |
| |||
89 | 97 | | |
90 | 98 | | |
91 | 99 | | |
| 100 | + | |
92 | 101 | | |
93 | 102 | | |
94 | 103 | | |
95 | 104 | | |
96 | 105 | | |
| 106 | + | |
97 | 107 | | |
98 | 108 | | |
99 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
100 | 116 | | |
101 | 117 | | |
102 | 118 | | |
| |||
112 | 128 | | |
113 | 129 | | |
114 | 130 | | |
| 131 | + | |
115 | 132 | | |
116 | 133 | | |
117 | 134 | | |
| |||
142 | 159 | | |
143 | 160 | | |
144 | 161 | | |
| 162 | + | |
145 | 163 | | |
146 | 164 | | |
147 | 165 | | |
| |||
180 | 198 | | |
181 | 199 | | |
182 | 200 | | |
| 201 | + | |
183 | 202 | | |
184 | 203 | | |
185 | 204 | | |
186 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
187 | 209 | | |
188 | 210 | | |
189 | 211 | | |
| |||
209 | 231 | | |
210 | 232 | | |
211 | 233 | | |
212 | | - | |
| 234 | + | |
213 | 235 | | |
214 | 236 | | |
215 | 237 | | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
216 | 243 | | |
217 | | - | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
218 | 266 | | |
219 | 267 | | |
| 268 | + | |
220 | 269 | | |
221 | | - | |
| 270 | + | |
222 | 271 | | |
223 | 272 | | |
| 273 | + | |
224 | 274 | | |
225 | | - | |
| 275 | + | |
| 276 | + | |
226 | 277 | | |
227 | 278 | | |
| 279 | + | |
228 | 280 | | |
229 | 281 | | |
230 | | - | |
| 282 | + | |
| 283 | + | |
231 | 284 | | |
232 | 285 | | |
| 286 | + | |
233 | 287 | | |
234 | | - | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
235 | 302 | | |
236 | 303 | | |
237 | 304 | | |
| |||
241 | 308 | | |
242 | 309 | | |
243 | 310 | | |
| 311 | + | |
244 | 312 | | |
245 | 313 | | |
246 | 314 | | |
| |||
253 | 321 | | |
254 | 322 | | |
255 | 323 | | |
| 324 | + | |
256 | 325 | | |
257 | 326 | | |
258 | 327 | | |
259 | 328 | | |
| 329 | + | |
260 | 330 | | |
261 | 331 | | |
262 | 332 | | |
263 | 333 | | |
| 334 | + | |
264 | 335 | | |
265 | 336 | | |
266 | 337 | | |
267 | 338 | | |
268 | 339 | | |
| 340 | + | |
269 | 341 | | |
270 | 342 | | |
271 | 343 | | |
| |||
394 | 466 | | |
395 | 467 | | |
396 | 468 | | |
| 469 | + | |
397 | 470 | | |
398 | 471 | | |
399 | 472 | | |
400 | 473 | | |
401 | 474 | | |
402 | 475 | | |
| 476 | + | |
403 | 477 | | |
404 | 478 | | |
405 | 479 | | |
406 | 480 | | |
| 481 | + | |
407 | 482 | | |
408 | 483 | | |
409 | 484 | | |
| |||
412 | 487 | | |
413 | 488 | | |
414 | 489 | | |
| 490 | + | |
415 | 491 | | |
416 | 492 | | |
417 | 493 | | |
418 | 494 | | |
419 | | - | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
420 | 498 | | |
421 | 499 | | |
422 | 500 | | |
423 | 501 | | |
| 502 | + | |
424 | 503 | | |
425 | 504 | | |
426 | 505 | | |
| |||
438 | 517 | | |
439 | 518 | | |
440 | 519 | | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
441 | 526 | | |
442 | 527 | | |
443 | 528 | | |
| |||
463 | 548 | | |
464 | 549 | | |
465 | 550 | | |
466 | | - | |
| 551 | + | |
467 | 552 | | |
468 | 553 | | |
469 | 554 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
294 | 294 | | |
295 | 295 | | |
296 | 296 | | |
297 | | - | |
298 | | - | |
299 | | - | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
300 | 308 | | |
301 | 309 | | |
302 | 310 | | |
| |||
0 commit comments