Skip to content

Make BTreeMap::new() not allocate #50266

Closed
@Gankra

Description

@Gankra

Currently, BTreeMap::new() allocates an empty root node. This is in spite of all of our other collections managing to avoid this. In #50240 it was demonstrated that there's massive wins to be had by avoiding allocating here. In the past we avoided implementing this because it simplified the code of BTreeMap a lot (which is already pretty gnarly code).

I see two ways to do this

  • Wrap everything in Options, adding extra branches on accesses to iterators and the map itself.
  • Do lots of clever shit, introducing minimal branches on access.

Some examples of clever shit:

  • The core Range iterator primitive can always always be initialized with two NonZero::dangling() pointers and len = 0. The existing branches will then do the correct thing. (this is how empty slices generally work)

  • By changing the layout of LeafNode to have the metadata first, we can statically allocate a LeafNode<u64, u64> (say) for all empty instances of BTreeMap to share. get/remove queries will then naturally work correctly without extra branches. See thin-vec for an example of doing this. An extra branch will probably need to be added to insert to check if we're pointing at the static singleton; not a big deal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions