{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreiasujl7vzgqcu465j5qfmvveql2qefde2i2pbmjzkuk7fid4enxye",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mkqfcgvocgc2"
  },
  "path": "/t/could-collections-hypothetically-store-keys-and-values-inline/24195#post_17",
  "publishedAt": "2026-04-30T18:41:15.000Z",
  "site": "https://internals.rust-lang.org",
  "tags": [
    "[1]",
    "↩︎"
  ],
  "textContent": "As a note, small {collection} optimization is _less_ necessary in Rust than it is in a language like C++. C++ has default copy semantics, so passing around `std::string` as a function argument is _safe_ (protecting you from shared mutation and/or use-after-move errors) but results in a _lot_ of extra string copies. When you have a bunch of copies and most strings are ≤22 bytes, thus fitting in the stack space necessary for the string already (on 64bit targets), you get a huge benefit from making those string copies into trivial copies instead of heap duplication.\n\nBut in Rust, `&str` existed from day one, gets used by default instead of passing `String` by value, and does not suffer from requiring developer enforcement of lifetimes. Furthermore, when `String` is passed by value because indefinite ownership is required, it's an ownership transferring trivial move, and duplicating the heap memory requires a `.clone()` call[1].\n\nEven comparing to a runtime for a scripting language like JavaScript or Lua, there roughly everything is a hashtable, so optimizing simple objects to not use the full dynamic machinery is a large cross-cutting performance improvement. But in Rust, those simple types won't be maps, they'll be their own static types, so collection types don't have to be optimized for the tiny use case.\n\nIt would be great if we could have e.g. `Vec<T, SmallStorage<23>>` and such so those cases that do benefit from small {collection} optimization can do so without abandoning the standard library's well tested API.\n\nais523:\n\n> For example, storing the capacity in `Vec` seems like double-storing to me.\n\nWhile this is a minor storage optimization, note that this likely defeats most peephole (i.e. LLVM) optimization, as now optimization can't easily track and know capacity information. Since the allocator is dynamically linked, its reported capacity might even change between queries, as far as the optimizations know!\n\nFurthermore, Rust has made a conscious (and imho correct) choice for global general purpose de/allocation to always provide the size/align of the allocated slot. Any cooperation with the allocator would need to happen with some `Vec<T, A>` which is not `Vec<T, Global>`, and the guarantee _only_ applies to the latter instantiation.\n\nyaksher:\n\n> This is not a “small map optimization”\n\nIt is a form of it, yes. When you exceed the allocated inline space, all of the map is transferred to the heap. The Rust `enum` overlaps the `Heap` and `Inline` case, using an invalid value of one to mark when the other is in use so the size equals that of the larger variant.\n\nBecause Rust is statically typed, types _must_ have a fixed stack size. `HashMap` is currently 6×`usize`. You'll be hard-pressed to fit more than one key/value pair in that space. If you have a use case where most of your maps only have one int-string entry... maybe you _shouldn't_ be using the general purpose stdlib `HashMap`.\n\nAs for layout optimization within the heap, hashbrown (the backing hashtable implementation for std) implements the SwissTable implementation, storing roughly `Box<dyn<N: usize> ([(K, V); N], [CtrlByte; N])>`. Rust was built with a default capability for trivial destructive moves, so there's nowhere near the default present in e.g. the C++ STL of defensively boxing things to provide address stability and guarantee cheap relocation (of the pointer in the collection).\n\n* * *\n\n  1. Or also whatever the final form of “`use` closures” ends up being. Think `move` closures except clone-capturing instead of move-capturing any handle-like (e.g. reference-counting) captures. ↩︎\n\n\n",
  "title": "Could collections hypothetically store keys and values inline?"
}