EA open sources their internal version of STL
github.com
github.com
Differences between std STL and EASTL
First, EASTL provides a set of containers, iterators, and algorithms that are identical in interface and behavior to std STL versions with one exception: allocators. EASTL has a different allocator specification which is simpler, more efficient, more flexible, and easier to use than std::allocator. Both std::allocator and eastl::allocator are described below. EASTL follows the defect reports and TR1 as well. EASTL additionally provides and uses some of the TR1 functionality as well, including most significantly the smart pointers, type traits, and hashing containers.
Second, EASTL provides extension functionality to the above containers, iterators, and algorithms. An example of this is the push_back(void), set_capacity(size), and validate() functions added to eastl::vector. The majority of these extensions are driven by the need for higher performance (push_back(void)), higher clarity (set_capacity), or higher debuggability (validate()). There are about 30 such extensions to the various entities in the library. These are described in detail below.
Third, EASTL provides additional containers and algorithms that don't correspond to std STL. These include intrusive_list, vector_map, fixed_hash_set, slist, ring_buffer, radix_sort, has_trivial_relocate, and others. These are described in detail below.
There are additional differences not related to the functional specification. They include a programming philosophy that emphasizes readability, consistency, and optimal performance on limited hardware.
I've missed all of these things greatly since leaving EA.
Ranting aside, I'm most curious to look at any optimizations they've made.
If you know the vector isn't going to be enormous you can swap two of those pointers for unsigned integers, cutting overhead down to 16 bytes total. If you know more about your data and usage patterns you can probably get it further. For very small vectors of largely static data you might trade one of the integers for linear-time insertion and deletion. If capacity is known at compile-time you can make it part of the type. If you know that size() will always equal capacity() you can get rid of the size int.
It's also worth noting that you don't have to double your storage on every reallocation to avoid linear-time insertions - you just have to multiply it by some constant that's greater than one. If you don't know how many reallocs you're going to do, but you know that it isn't many, you might want to just multiply your capacity by 1.1 every time to avoid a lot of wasted space. Assuming, of course, that you're happy with bringing floating point computation in, and that you've thought about how you're going to increase the capacity of a vector of size 1...
I think STL is a great set of libraries, but I also think they're sometimes too easy to use if you don't consider alternative implementations and the impact of each way.
That doesn't sound right at all. Of course, if you add or remove objects at the vector's head, all of its data will be moved, though probably not reallocated. But if you have a need for frequent additions and deletions anywhere but the tail of the vector, you picked a wrong data structure. Double ended queue (<deque>) would would've suited you much better.
Moving to a fixed size array in C++ I saw an easy 50% drop in CPU usage.
Did you reimplement element addition/deletion logic from scratch?
Insertions and deletions at either end are O(1), but inserting/deleting in the middle is costly.
If that was the case, you were doing something wrong.
Somebody said computer science is solving yesterdays problems on tomorrows hardware, the rest of science is solving tomorrows problems on yesterdays hardware
vector<T> vec;
while(getData(v)) { vec.push_back(v); }
Incidentally, I asked someone about memory management in an interview for a C++ position. He said he wrote his own memory manager (object pool, basically), and never even bothered to use "new" or "delete".
Personally, I'm sticking to Haskell...
And the reason you don't use garbage collection is because real-time games can't afford a GC pause.
You also don't want your code to fail after weeks of runtime with an alloc error, if it's going to run out of memory you want it to fail at the start.
That's not to say that other languages aren't capable of these things, of course.
(I spent seven years working for EA, and I contributed to EASTL while I was there.)
Here are first rough benchmarks: http://msinilo.pl/blog/?p=668
But don't say it like that, it's against the license ;p