Repository navigation
Conversation
Results are unchanged. * Recompute the total capacity only when a compaction adds a level. * Merge from the other sketch's levels by reference, and select the merge source with the comparison result for item types without drop glue. * Shrink the new top level when a compaction adds one; it held the downsampled half in the compacted level's buffer. * Check a sorted level's minimum/maximum bounds at its first and last items and scan the whole level only when one is out of range. * Merge pairs of levels straight from the sketch in the first sorted-view round. * Compare `KllFloat` with `<` and `>` instead of `partial_cmp().unwrap()`. Add reference tests for sorted views, merges, long-stream invariants, and the position reported for an out-of-range item. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tisonkun
reviewed
Nov 6, 2026
Member
There was a problem hiding this comment.
But self.0.partial_cmp(&other.0).unwrap() just work well?
We don't forbid unwrap especially you already prove that the branch is unreachable.
Contributor
Author
There was a problem hiding this comment.
Thanks, makes sense. I've restored partial_cmp().unwrap() (b7e4fcf). For the record, it was there for speed rather than to avoid unwrap(): the compiler keeps the NaN check and panic branch in every comparison, and on this branch </> made quantile/quantiles take about 19% less time. That part of the gain is gone now, and I've updated the numbers in the description.
Restore the comparison from main, as asked in review. The order of retained items and every result are unchanged. Co-Authored-By: Claude Opus 5.5 <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.
Summary
KllSketchnow does less work per update, merge, deserialization, and sorted-view query. Results of every operation are unchanged: same retained items, same tie order, same serialized bytes, same deserialization errors.On the benchmark machine, updates take 7% to 13% less time,
merge16% less,deserialize13% less, andquantileandquantiles14% less (time ratios 0.93 to 0.84, see "Results").mergereads the other sketch's levels by reference instead of cloning them first. For item types without drop glue, the sorted merge selects the source with the comparison result instead of branching on it.Results
Main benchmark suite, 8 rounds. The ratio is the time after this change divided by the time before; below 1 is faster.
kll::update::update/1000kll::update::update/10000kll::update::update/100000kll::merge::mergekll::serde::deserializekll::query::quantile/0.5kll::query::batch_quantileskll::query::rank,quantile/0.0,quantile/1.0, andsorted_view_quantileare unchanged within noise (0.996 to 1.007); they do not run the changed code.Additional workloads that are not in the repository's suite (8 rounds, k = 200 unless noted):
f32/i64itemsf64, k = 8 / k = 1000f32/i64itemsf32/i64itemsf64k = 1000quantile,f64k = 1000Memory: I measured the exact heap owned by a sketch with a counting allocator and a fixed random seed, so that this branch and
maindraw identical compaction bits. It was sampled after each of the first 20,000 updates (and every 97th update up to 300,000) and after each of 256 merges, for k = 8, 50, 200, 1000, withf32andf64items and merge parts of 50, 500, and 5,000 items. Of 186,160 samples, none is higher than before; the mean is 4% to 16% lower.Scope of the results
The gains come from doing less work, not from a CPU feature, but they depend on the workload:
Stringitems, updates take 2% less time and deserialization 11% less;mergeandquantileare about the same (ratios 1.00 and 0.97).shrink_to_fitadds one reallocation per added level. Removing it did not change the time of that merge (2.50 µs either way).quantile(about 1 to 8 ms) right after building many sketches, this branch was sometimes slower thanmain(i64, k = 200: 0.96 ms instead of 0.81 ms in 7 of 10 processes), with the same instruction count but more mispredicted branches;maindid not vary this way. In longer runs, both in that harness and in a program that builds a single sketch,quantilewas consistently faster (time ratios 0.72 to 0.84 forf64andi64, k = 8 and 200). I don't know the cause.kll::serde::serialize, which this change does not touch, measured 1.01.All numbers come from one machine; I have not measured others.
Checks
cargo x check,cargo x lint,cargo x test, andcargo +1.86.0 x testpass.Measured on one machine (2x Xeon E5-2660 v3, Linux 6.8) against
mainat4ba130ewith the repository's benchmark runner (kll:: --repeat 3), pinned to one core, with the two builds alternating over 8 rounds and the same fixed random seed in both; ratios are the geometric mean of per-round median ratios.