Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the article Generic<Programming> Typed Buffers completely obsolete with C++ 11?

I am reading Generic<Programming> Typed Buffers, a pretty old article from Andrei Alexandrescu.

I'm wondering if it still makes sense. In his article Alexandrescu points out some issues with std::vector when performance is critical:

  • Unnecessary data initialization when allocating a vector which I think can be solved using std::vector::reserve
  • expensive move operation which is solved with C++11 and move semantics
  • most compiler do not optimize std::vector for type such as char by using std::memcpy and std::memmove. This is untrue now for mainstream compilers (from what I have seen).
  • Exponential growth. You can not shrink the capacity of the std::vector to fit the size with a simple method call. Which is also untrue since C++11 with std::vector::shrink_to_fit()

My question is, is this article completely obsolete, can I now rely on vector (including custom allocator if necessary) to have a fast contiguous buffer?

like image 280
vac Avatar asked Jul 21 '14 14:07

vac


1 Answers

C++11 largely closes the gap between std::vector and raw arrays (move semantics and shrink_to_fit solve some of Alexandrescu's points), but the niche still exists to some extent; std::vector continues to value-initialize elements; reserve doesn't help because you can't access the reserved memory. You can hack around this with a custom allocator, but it's far from satisfactory.

From the other end, unique_ptr<T[]> makes holding a buffer in your container class much more straightforward as it largely solves exception-safety issues. The TS dynarray, which offers fixed-size allocation at construction with default-initialization, looks likely to close much of the remainder of the gap.

The remaining niche that Alexandrescu's generic buffers occupy is to offer default-initialized elements with O(n) shrink and grow operations; these are generally not useful as a component of container classes and if required can be written as non-member functions.

like image 83
ecatmur Avatar answered Oct 13 '22 20:10

ecatmur