What is the difference between std::vector and llvm::SmallVector? which one to use when?
llvm::SmallVector
is a vector optimized for small arrays. This optimization comes from not performing heap allocations for a limited number of elements.
In the event that you add more elements than are described to be allocated using automatic storage it will fall back to the behavior of std::vector
and allocate larger and larger arrays.
llvm::SmallVector<int, 10> smallVector;
for(int i = 0; i < 10; i++)
{
smallVector.push_back(i);
}
// No heap allocations have been performed up to this point.
smallVector.push_back(11);
// Only 10 spaces for non heap allocated elements,
// so the push_back above causes a heap allocation.
SmallVector can have a performance benefit when you know you will consistently have a small number of elements and won't run into heap allocations. This performance benefit comes at the cost of exception safety and a dependency on the llvm libraries.
What is the difference between std::vector and LLVM::SmallVector?
I assume that you are familiar with the standard vector. llvm::SmallVector is described in the documentation:
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
It contains some number of elements in-place, which allows it to avoid heap allocation when the actual number of elements is below that threshold. This allows normal "small" cases to be fast without losing generality for large inputs.
Note that this does not attempt to be exception safe.
which one to use when?
Use std::vector when:
- You need exception safety OR
- You don't want extra dependencies beyond the standard library OR
- The container isn't a bottleneck OR
- Performance doesn't even matter OR
- The vector is going to be large anyway, so the optimization wouldn't have an impact
Use a small-optimized implementation (such as llvm::SmallVector, or another implementation) when
- None of the above applies
Also what happens if we push more elements in llvm::SmallVector than its size?
When the internal small buffer is exhausted, a dynamic buffer is allocated and it will behave like std::vector
.