When is it "morally" correct to use smallvec?

First, some reasons not to use SmallVec:

  • When it spills onto the heap, it’s just a worse Vec.
  • It wastes more space when empty.
  • It takes up inline space in structs/containers, which can decrease cache locality of the fields outside of the vector.
  • Moving a SmallVec by value may be much more expensive than moving a Vec, and LLVM does not always ellide moves perfectly. This means you occasionaly need to re-architect some code in order to use SmallVec efficiently.
  • It uses unsafe code. While we do a lot to audit and test it, soundness bugs have slipped through a few times.

Reasons that SmallVec might be a big win:

  • You know that your vector will hold a very small number of items most of the time, and only rarely need to hold more. (SmallVec may speed up the common case a lot, while slightly slowing down the uncommon case.)
  • Your vector is local to the stack of a function that is called frequently. (SmallVec will usually be allocated on the stack, saving the need for frequent heap allocations and deallocations.)
  • You want cache locality between the items in your vector and other data stored alongside it. (SmallVec eliminates a pointer indirection between the vector and its container.)

I'd probably want at least two of these reasons to be true, or some other strong evidence of a performance win, before I would reach for SmallVec. (Disclosure: I’m one of the maintainers of the smallvec crate.)

28 Likes