Repository navigation
Conversation
compact sorts updates whose prefix updates[..clean] is already sorted and consolidated. TimelyDataflow#751 moved it to sort_unstable_by, which sorts the whole list again; the stable sort finds the sorted run and merges the new updates into it in linear time. On a 2,000-operator dataflow advanced one round at a time, progress tracking takes 20% fewer instructions (callgrind) and 9-13% less time per round, for 0.2% more heap allocations: the stable sort allocates scratch only past its 4 KiB stack buffer.
|
Thanks! I can't seem to keep up with the Rust sort infrastructure (or what is real vs my memory about it). I have a maybe helpful hint, if you are getting beaten up by these computations. The recent timely releases allow operators to express a There's a blog post here: https://github.com/frankmcsherry/blog/blob/master/posts/2026-03-19.md The main caveat is that the DD half of the story isn't merged yet, but you could check it out if you like. It did reveal that the I tested a few Happy to explain more, but also for the moment it's work in progress that should be landing, rather than released goods. |
ChangeBatch::compactsortsupdates, whose prefixupdates[..clean]is already sorted and consolidated, followed by the updates added since. #751 moved it fromsort_bytosort_unstable_by. The unstable sort sorts the whole list again. The stable sort finds the sorted run and merges the new updates into it in linear time. This PR goes back tosort_byhere, with a comment saying why. The other call sites #751 changed are left as they are.Measured on master (da506a1, v0.32.0), release build, with the program below: one input, a region of N
maps (a chain) or N parallelmaps concatenated (a fan), advanced one round at a time.sort_unstable_by(master)sort_by(this PR)The stable sort allocates scratch only past its 4 KiB stack buffer, so small batches still allocate nothing. Only the large ones, where the merge pays off most, allocate.
An alternative I tried: sort only
updates[clean..]in place (unstable), and run the stable sort only when that tail overlaps the prefix. It came out at 2,047 M instructions (−9%) and 325,488 allocations, so the plain stable sort wins.Found while moving Improv from timely 0.13 to 0.32: an edit at the root of a 2,000-measure differential-dataflow graph had become 13–37% slower, almost all of it in
ChangeBatch::compact. With this change it is back to within 5% of 0.13.cargo test --workspace --all-targets,cargo test --docandcargo clippy --workspace --all-targetspass, andcargo checkon 1.86 (the MSRV).The benchmark
Run as
progress-bench chain 2000 300andprogress-bench fan 2000 300.