|
> The only thing you can really quibble about with std::vector is [...] That's actually not true, though I certainly don't fault you for believing it :-) but there are definitely more things to quibble about around vector if you're serious about performance.
As an example, try writing a can_fit(n) function, which tells you whether the vector can fit n elements without reallocating. Observe the performance difference between (a) a smart manual version, (b) a naive manual version, and (c) the only STL version: https://godbolt.org/z/88sfM1sxW #include <vector>
template<class T>
struct Vec { T *b, *e, *f; };
template<class T>
bool can_fit_fast(Vec<T> const &v, size_t n) {
return reinterpret_cast<char*>(v.f) - reinterpret_cast<char*>(v.e) >= n * sizeof(T);
}
template<class T>
bool can_fit(Vec<T> const &v, size_t n) {
return v.f - v.e >= n;
}
template<class T>
bool can_fit(std::vector<T> const &v, size_t n) {
return v.capacity() - v.size() >= n;
}
struct S { size_t a[3]; };
template bool can_fit_fast(Vec<S> const &, size_t);
template bool can_fit(Vec<S> const &, size_t);
template bool can_fit(std::vector<S> const &, size_t);
|
If you change can_fit(Vec<S>) to:
You end up with code that looks pretty similar to the can_fit(std::vector<S>) overload (the same for clang, a bit different for GCC), so it does seem it might be something about the extra pointer math that can't be safely reduced, and the casts aren't really relevant.(I'm also a bit surprised that can_fit_fast produces different assembly than the Vec can_fit overload)