Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional support for custom TreeMap allocator #45

Merged
merged 2 commits into from
Nov 17, 2024
Merged

Conversation

declanvk
Copy link
Owner

Description

  • Modify the TreeMap interface so that it exposes a new generic parameter for the allocator, defaulting to the Rust global allocator.
  • Modify the internal tree operations to use the allocator stored in the tree for insert/delete/clone/dealloc operations
  • Add a new feature flag and optional dependency to consume the Allocator trait on the stable toolchain, also integrate with the nightly feature flag + toolchain to use that trait.
  • Also fix a bunch of clippy lints that are coming in on the latest nightly toolchains
    • Converting explicit lifetimes to '_

Note: The current OOM behavior is to panic. I may change this in the future to support an explicit Err(...), but not to start at least.

Motivation
I think custom allocators are a very useful feature for making the the library more flexible and useful in no_std environments, or other non-standard scenarios. I was even able to experiment with using bumpalo as the custom allocator, which I think is neat.

Testing Done
I added some unit tests which create various custom allocators and use those to create/update/query/delete from TreeMap.

**Description**
 - Modify the TreeMap interface so that it exposes a new generic
   parameter for the allocator, defaulting to the Rust global
   allocator.
 - Modify the internal tree operations to use the allocator stored
   in the tree for insert/delete/clone/dealloc operations
 - Add a new feature flag and optional dependency to consume the
   `Allocator` trait on the stable toolchain, also integrate with the
   `nightly` feature flag + toolchain to use that trait.
 - Also fix a bunch of clippy lints that are coming in on the latest
   nightly toolchains
   - Converting explicit lifetimes to `'_`

Note: The current OOM behavior is to panic. I may change this in the
future to support an explicit `Err(...)`, but not to start at least.

**Motivation**
I think custom allocators are a very useful feature for making the
the library more flexible and useful in `no_std` environments, or
other non-standard scenarios. I was even able to experiment with
using `bumpalo` as the custom allocator, which I think is neat.

**Testing Done**
I added some unit tests which create various custom allocators and
use those to create/update/query/delete from `TreeMap`.
@declanvk
Copy link
Owner Author

./scripts/bench-against.sh main

Perf results:

iai_callgrind::bench_clone_group::bench_clone with_prefixes:...
  Baselines:                       |7acc4f8
  Instructions:            20037665|20056386        (-0.09334%) [-1.00093x]
  L1 Hits:                 26548133|26566862        (-0.07050%) [-1.00071x]
  L2 Hits:                    53269|53262           (+0.01314%) [+1.00013x]
  RAM Hits:                   53912|53911           (+0.00185%) [+1.00002x]
  Total read+write:        26655314|26674035        (-0.07018%) [-1.00070x]
  Estimated Cycles:        28701398|28720057        (-0.06497%) [-1.00065x]
iai_callgrind::bench_clone_group::bench_clone dictionary:...
  Baselines:                       |7acc4f8
  Instructions:            23680468|23718793        (-0.16158%) [-1.00162x]
  L1 Hits:                 31492939|31531177        (-0.12127%) [-1.00121x]
  L2 Hits:                    65580|65669           (-0.13553%) [-1.00136x]
  RAM Hits:                   64472|64470           (+0.00310%) [+1.00003x]
  Total read+write:        31622991|31661316        (-0.12105%) [-1.00121x]
  Estimated Cycles:        34077359|34115972        (-0.11318%) [-1.00113x]
iai_callgrind::bench_lookup_group::bench_lookup_single first_key:...
  Baselines:                       |7acc4f8
  Instructions:                 217|217             (No change)
  L1 Hits:                      261|261             (No change)
  L2 Hits:                        7|7               (No change)
  RAM Hits:                      16|16              (No change)
  Total read+write:             284|284             (No change)
  Estimated Cycles:             856|856             (No change)
iai_callgrind::bench_lookup_group::bench_lookup_single last_key:...
  Baselines:                       |7acc4f8
  Instructions:                 281|281             (No change)
  L1 Hits:                      332|333             (-0.30030%) [-1.00301x]
  L2 Hits:                        0|0               (No change)
  RAM Hits:                      19|18              (+5.55556%) [+1.05556x]
  Total read+write:             351|351             (No change)
  Estimated Cycles:             997|963             (+3.53063%) [+1.03531x]
iai_callgrind::bench_lookup_group::bench_lookup_multiple dictionary:...
  Baselines:                       |7acc4f8
  Instructions:              583608|583608          (No change)
  L1 Hits:                   743573|743573          (No change)
  L2 Hits:                      499|500             (-0.20000%) [-1.00200x]
  RAM Hits:                      32|31              (+3.22581%) [+1.03226x]
  Total read+write:          744104|744104          (No change)
  Estimated Cycles:          747188|747158          (+0.00402%) [+1.00004x]
iai_callgrind::bench_remove_group::bench_remove_single first_key:...
  Baselines:                       |7acc4f8
  Instructions:            11218882|11106388        (+1.01288%) [+1.01013x]
  L1 Hits:                 15711498|15500829        (+1.35908%) [+1.01359x]
  L2 Hits:                    64608|64609           (-0.00155%) [-1.00002x]
  RAM Hits:                      93|85              (+9.41176%) [+1.09412x]
  Total read+write:        15776199|15565523        (+1.35348%) [+1.01353x]
  Estimated Cycles:        16037793|15826849        (+1.33282%) [+1.01333x]
iai_callgrind::bench_remove_group::bench_remove_single last_key:...
  Baselines:                       |7acc4f8
  Instructions:            11217928|11105431        (+1.01299%) [+1.01013x]
  L1 Hits:                 15710184|15499506        (+1.35926%) [+1.01359x]
  L2 Hits:                    64591|64592           (-0.00155%) [-1.00002x]
  RAM Hits:                      82|78              (+5.12821%) [+1.05128x]
  Total read+write:        15774857|15564176        (+1.35363%) [+1.01354x]
  Estimated Cycles:        16036009|15825196        (+1.33214%) [+1.01332x]
iai_callgrind::bench_remove_group::bench_remove_multiple dictionary:...
  Baselines:                       |7acc4f8
  Instructions:            11766164|11653735        (+0.96475%) [+1.00965x]
  L1 Hits:                 16424502|16214011        (+1.29820%) [+1.01298x]
  L2 Hits:                    63654|63669           (-0.02356%) [-1.00024x]
  RAM Hits:                    2024|2009            (+0.74664%) [+1.00747x]
  Total read+write:        16490180|16279689        (+1.29297%) [+1.01293x]
  Estimated Cycles:        16813612|16602671        (+1.27052%) [+1.01271x]
iai_callgrind::bench_insert_group::bench_insert_single first_key:...
  Baselines:                       |7acc4f8
  Instructions:            11219065|11106570        (+1.01287%) [+1.01013x]
  L1 Hits:                 15711835|15501155        (+1.35912%) [+1.01359x]
  L2 Hits:                    64601|64605           (-0.00619%) [-1.00006x]
  RAM Hits:                      61|59              (+3.38983%) [+1.03390x]
  Total read+write:        15776497|15565819        (+1.35347%) [+1.01353x]
  Estimated Cycles:        16036975|15826245        (+1.33152%) [+1.01332x]
iai_callgrind::bench_insert_group::bench_insert_single last_key:...
  Baselines:                       |7acc4f8
  Instructions:            11219550|11107051        (+1.01286%) [+1.01013x]
  L1 Hits:                 15712467|15501771        (+1.35917%) [+1.01359x]
  L2 Hits:                    64597|64604           (-0.01084%) [-1.00011x]
  RAM Hits:                      61|63              (-3.17460%) [-1.03279x]
  Total read+write:        15777125|15566438        (+1.35347%) [+1.01353x]
  Estimated Cycles:        16037587|15826996        (+1.33058%) [+1.01331x]
iai_callgrind::bench_insert_group::bench_insert_multiple dictionary:...
  Baselines:                       |7acc4f8
  Instructions:            12362492|12247869        (+0.93586%) [+1.00936x]
  L1 Hits:                 17278412|17065509        (+1.24756%) [+1.01248x]
  L2 Hits:                    67140|67131           (+0.01341%) [+1.00013x]
  RAM Hits:                     254|241             (+5.39419%) [+1.05394x]
  Total read+write:        17345806|17132881        (+1.24279%) [+1.01243x]
  Estimated Cycles:        17623002|17409599        (+1.22578%) [+1.01226x]
iai_callgrind::bench_iterator_group::bench_full_iterator dictionary:...
  Baselines:                       |7acc4f8
  Instructions:              196616|196616          (No change)
  L1 Hits:                   196620|196620          (No change)
  L2 Hits:                    32768|32768           (No change)
  RAM Hits:                       2|2               (No change)
  Total read+write:          229390|229390          (No change)
  Estimated Cycles:          360530|360530          (No change)
iai_callgrind::bench_iterator_group::bench_prefix_iterator empty:...
  Baselines:                       |7acc4f8
  Instructions:              198048|198048          (No change)
  L1 Hits:                   198408|198409          (-0.00050%) [-1.00001x]
  L2 Hits:                    32776|32776           (No change)
  RAM Hits:                      22|21              (+4.76190%) [+1.04762x]
  Total read+write:          231206|231206          (No change)
  Estimated Cycles:          363058|363024          (+0.00937%) [+1.00009x]
iai_callgrind::bench_iterator_group::bench_prefix_iterator specific_key:...
  Baselines:                       |7acc4f8
  Instructions:                 354|354             (No change)
  L1 Hits:                      407|404             (+0.74257%) [+1.00743x]
  L2 Hits:                        2|2               (No change)
  RAM Hits:                      25|28              (-10.7143%) [-1.12000x]
  Total read+write:             434|434             (No change)
  Estimated Cycles:            1292|1394            (-7.31707%) [-1.07895x]
iai_callgrind::bench_iterator_group::bench_prefix_iterator random_partial:...
  Baselines:                       |7acc4f8
  Instructions:                 506|506             (No change)
  L1 Hits:                      574|573             (+0.17452%) [+1.00175x]
  L2 Hits:                       15|15              (No change)
  RAM Hits:                      24|25              (-4.00000%) [-1.04167x]
  Total read+write:             613|613             (No change)
  Estimated Cycles:            1489|1523            (-2.23244%) [-1.02283x]
iai_callgrind::bench_iterator_group::bench_fuzzy_iterator zero:...
  Baselines:                       |7acc4f8
  Instructions:                5146|5149            (-0.05826%) [-1.00058x]
  L1 Hits:                     6585|6593            (-0.12134%) [-1.00121x]
  L2 Hits:                        7|7               (No change)
  RAM Hits:                      42|41              (+2.43902%) [+1.02439x]
  Total read+write:            6634|6641            (-0.10541%) [-1.00106x]
  Estimated Cycles:            8090|8063            (+0.33486%) [+1.00335x]
iai_callgrind::bench_iterator_group::bench_fuzzy_iterator specific_key:...
  Baselines:                       |7acc4f8
  Instructions:            30457744|29817016        (+2.14887%) [+1.02149x]
  L1 Hits:                 40044597|38992556        (+2.69806%) [+1.02698x]
  L2 Hits:                    64612|64575           (+0.05730%) [+1.00057x]
  RAM Hits:                     258|257             (+0.38911%) [+1.00389x]
  Total read+write:        40109467|39057388        (+2.69367%) [+1.02694x]
  Estimated Cycles:        40376687|39324426        (+2.67585%) [+1.02676x]
iai_callgrind::bench_iterator_group::bench_range_iterator full:...
  Baselines:                       |7acc4f8
  Instructions:              196752|196752          (No change)
  L1 Hits:                   196799|196800          (-0.00051%) [-1.00001x]
  L2 Hits:                    32773|32773           (No change)
  RAM Hits:                      13|12              (+8.33333%) [+1.08333x]
  Total read+write:          229585|229585          (No change)
  Estimated Cycles:          361119|361085          (+0.00942%) [+1.00009x]
iai_callgrind::bench_iterator_group::bench_range_iterator specific_key:...
  Baselines:                       |7acc4f8
  Instructions:                1023|1023            (No change)
  L1 Hits:                     1199|1197            (+0.16708%) [+1.00167x]
  L2 Hits:                       19|19              (No change)
  RAM Hits:                      33|35              (-5.71429%) [-1.06061x]
  Total read+write:            1251|1251            (No change)
  Estimated Cycles:            2449|2517            (-2.70163%) [-1.02777x]
iai_callgrind::bench_iterator_group::bench_range_iterator middle_third:...
  Baselines:                       |7acc4f8
  Instructions:               66662|66662           (No change)
  L1 Hits:                    66845|66843           (+0.00299%) [+1.00003x]
  L2 Hits:                    10953|10953           (No change)
  RAM Hits:                      34|36              (-5.55556%) [-1.05882x]
  Total read+write:           77832|77832           (No change)
  Estimated Cycles:          122800|122868          (-0.05534%) [-1.00055x]

Mostly small negative changes (+1%-2% in instructions and L1 hits), but I'm not too concerned.

@declanvk declanvk merged commit e021373 into main Nov 17, 2024
4 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.

1 participant