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.)