Skip to content

Fixes for a bunch of prune issues - #141

Merged
luketpeterson merged 3 commits into
masterfrom
bugfix/prune_fixes
Sep 28, 2026
Merged

luketpeterson merged 3 commits into
masterfrom
bugfix/prune_fixes

Conversation

@luketpeterson

Copy link
Copy Markdown
Collaborator

#138 was the tip of the iceberg. Hopefully this PR makes prune and the prune flag consistent.

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Bench A/B vs base: done

job log · 2026-09-26 17:31:20 UTC

base e4b167c → head 387c0a7, 3 round(s), median of each run averaged; negative is faster

bench cases geomean largest gain largest loss >5% faster >5% slower
shakespeare 7 -1.8% -11.7% shakespeare/shakespeare_sentences_val_count +9.1% shakespeare/shakespeare_words_val_count 2 1
cities 5 -0.5% -3.0% cities/cities_val_count_act +2.3% cities/cities_val_count 0 0
sparse_keys 96 +0.5% -6.2% sparse_val_count_bench/125 +21.8% sparse_zipper_cursor/50 3 11
binary_keys 77 -2.1% -10.9% binary_descend_until/1000 +2.2% binary_zipper_step_iter/1600 7 0
superdense_keys 104 -0.8% -10.4% superdense_k_path_iter/500 +4.8% superdense_insert/400 10 0
act_paths 46 -0.9% -5.0% act_paths/round_trip +2.1% size_dense_paths_to_act/50000 0 0
zipper_head_owned 0
product_zipper 4 -0.3% -1.0% product_zipper/generic_pathmap_pathmap +0.7% product_zipper/generic_act_act 0 0
34 case(s) moved more than 5%
bench case base head change
sparse_keys sparse_zipper_cursor/50 644 ns 784 ns +21.8%
sparse_keys sparse_zipper_cursor/100 1.31 µs 1.54 µs +17.9%
sparse_keys sparse_zipper_cursor/200 2.59 µs 3.05 µs +17.8%
sparse_keys sparse_zipper_cursor/400 5.62 µs 6.61 µs +17.5%
sparse_keys sparse_k_path_iter/1600 27.39 µs 31.20 µs +13.9%
sparse_keys sparse_k_path_iter/50 797 ns 901 ns +13.0%
sparse_keys sparse_k_path_iter/200 3.20 µs 3.61 µs +12.8%
sparse_keys sparse_k_path_iter/800 14.53 µs 16.39 µs +12.8%
sparse_keys sparse_k_path_iter/100 1.58 µs 1.78 µs +12.7%
sparse_keys sparse_k_path_iter/400 6.84 µs 7.67 µs +12.1%
shakespeare shakespeare/shakespeare_sentences_val_count 3.05 ms 2.69 ms -11.7%
binary_keys binary_descend_until/1000 68.03 µs 60.63 µs -10.9%
superdense_keys superdense_k_path_iter/500 3.62 µs 3.25 µs -10.4%
binary_keys binary_descend_until/500 32.46 µs 29.13 µs -10.3%
superdense_keys superdense_k_path_iter/4000 29.05 µs 26.17 µs -9.9%
superdense_keys superdense_k_path_iter/8000 58.05 µs 52.35 µs -9.8%
superdense_keys superdense_k_path_iter/2000 14.50 µs 13.09 µs -9.7%
superdense_keys superdense_k_path_iter/16000 116.13 µs 105.03 µs -9.6%
binary_keys binary_descend_until/250 15.61 µs 14.15 µs -9.4%
superdense_keys superdense_k_path_iter/1000 7.28 µs 6.60 µs -9.4%
shakespeare shakespeare/shakespeare_words_val_count 314.23 µs 342.80 µs +9.1%
binary_keys binary_insert/1600 183.17 µs 167.53 µs -8.5%
binary_keys binary_zipper_iter/50 1.25 µs 1.16 µs -7.2%
superdense_keys superdense_val_count_bench/20000 9.72 µs 9.05 µs -6.9%
binary_keys binary_descend_until/2000 188.13 µs 175.87 µs -6.5%
sparse_keys sparse_val_count_bench/125 298 ns 279 ns -6.2%
binary_keys binary_zipper_iter/100 2.39 µs 2.25 µs -6.1%
sparse_keys sparse_get/250 3.59 µs 3.81 µs +6.1%
shakespeare shakespeare/shakespeare_sentences_insert 54.27 ms 51.07 ms -5.9%
sparse_keys join_sparse/50 637 ns 601 ns -5.8%
superdense_keys superdense_get/16000 227.27 µs 214.57 µs -5.6%
sparse_keys sparse_zipper_step_iter/800 135.43 µs 128.17 µs -5.4%
superdense_keys superdense_drop_head/1000 15.93 µs 15.12 µs -5.1%
superdense_keys superdense_drop_head/2000 22.07 µs 20.96 µs -5.0%

Full tables per bench are in the job log and the bench-out artifact.

Comment thread src/trie_node.rs
/// Dangling paths may be pruned down to `prune_limit` bytes of `key`.
/// `usize::MAX` disables pruning.
/// WARNING: This method may leave the node empty
fn node_remove_val(&mut self, key: &[u8], prune: bool) -> Option<V>;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prune_limit seems to commit harder to the idea of pruning, and in that direction I like it. However, usize::MAX is less ergonomic than true, and I don't think that's the right place to take the API. I believe we should have a "prune-free" API, and an API that gives you the control if you want it. I don't know what this looks like yet, it could be node_remove_val(&mut self, key: &[u8]) and node_remove_val_dangle(&mut self, key: &[u8], prune_limit: usize)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't exposed. This is the zipper-to-node contract. The externally-facing API is unchanged.

Comment thread src/zipper_tracking.rs
let mut zipper = all_paths.read_zipper();
match Conflict::check_for_lock_along_path(path, &mut zipper) {
fn check_for_write_conflict<C, ConflictF: FnOnce(&[u8])->C>(path: &[u8], zipper: &mut WriteZipperOwned<()>, conflict_f: ConflictF) -> Result<(), C> {
zipper.reset();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see the performance impact of tracking with this change

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added prune benchmarks. It's almost twice as fast to create tracked zippers. But with the _unchecked version of the calls used by mork, nothing changes in either direction.

@luketpeterson
luketpeterson merged commit ec818cf into master Sep 28, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants