views:

285

answers:

3

I know several (all?) STL implementations implement a "small string" optimization where instead of storing the usual 3 pointers for begin, end and capacity a string will store the actual character data in the memory used for the pointers if sizeof(characters) <= sizeof(pointers). I am in a situation where I have lots of small vectors with an element size <= sizeof(pointer). I cannot use fixed size arrays, since the vectors need to be able to resize dynamically and may potentially grow quite large. However, the median (not mean) size of the vectors will only be 4-12 bytes. So a "small string" optimization adapted to vectors would be quite useful to me. Does such a thing exist?

I'm thinking about rolling my own by simply brute force converting a vector to a string, i.e. providing a vector interface to a string. Good idea?

A: 

It was discussed years ago (and a few of the names in that thread may look a bit familiar :-) ), but I don't know of an existing implementation. I don't think I'd try to adapt std::string to the task. The exact requirements on the type over which std::basic_string aren't well stated, but the standard is pretty clear that it's only intended for something that acts a lot like char. For types that are substantially different, it might still work, but it's hard to say what would happen -- it was never intended for, and probably hasn't been tested with many types other than small integers.

When you get down to it, implementing std::vector from scratch (even including a small vector optimization) won't be terribly difficult.

Jerry Coffin
Implementing `std::vector` *correctly* from scratch is surprisingly hard. Of course, if you choose to ignore exception safety it becomes a lot easier, but then it's no longer a meaningful (or useful) `vector` implementation.
jalf
Thanks for the pointer - unfortunately the discussion never really reached a conclusion.Implementing my own vector wouldn't be all that difficult, I agree. However, I was hoping of just plugging in some ready made class and see the effect on memory consumption. I'm currently toying with various ideas of reducing our memory footprint and this is only one of them.
BuschnicK
When that is said, I do think a custom vector implementation would be the best way to achieve this. Wrapping the existing vector class would make it hard to exploit the object's size efficiently, and a custom vector isn't rocket science, as long as you're careful and know what you're doing.
jalf
Jerry Coffin
@Jerry: True, I don't think that can be done either. But at least it's a bit of a corner case, where you can probably live without the nothrow guarantee.
jalf
@Jerry: I don't know why swap would throw. The number of external buffers after swap is the same number as before swap, the number of small vector optimizations is the same after as before. There's no need for allocation, you just swap the small-vector flag along with the buffer pointer. (and that flag might be the LSB of the pointer, when sizeof(T) > 1)
Ben Voigt
+2  A: 

You can borrow the SmallVector implementation from LLVM. (header only, located in LLVM\include\llvm\ADT)

Thomas Petit
A: 

If T is a POD type why not basic_string instead of vector??

Lance Diduck