Tod
Tod

Reputation: 4688

STL Alternative

I really hate using STL containers because they make the debug version of my code run really slowly. What do other people use instead of STL that has reasonable performance for debug builds?

I'm a game programmer and this has been a problem on many of the projects I've worked on. It's pretty hard to get 60 fps when you use STL container for everything.

I use MSVC for most of my work.

Upvotes: 28

Views: 15672

Answers (15)

schoetbi
schoetbi

Reputation: 12866

There is also the ETL https://www.etlcpp.com/. This library aims especially for time critical (deterministic) applications

From the webpage:

The ETL is not designed to completely replace the STL, but complement it. Its design objective covers four main areas.

  • Create a set of containers where the size or maximum size is determined at compile time. These containers should be largely equivalent to those supplied in the STL, with a compatible API.
  • Be compatible with C++ 03 but implement as many of the C++ 11 additions as possible.
  • Have deterministic behaviour.
  • Add other useful components that are not present in the standard library.

The embedded template library has been designed for lower resource embedded applications. It defines a set of containers, algorithms and utilities, some of which emulate parts of the STL. There is no dynamic memory allocation. The library makes no use of the heap. All of the containers (apart from intrusive types) have a fixed capacity allowing all memory allocation to be determined at compile time. The library is intended for any compiler that supports C++03.

Upvotes: -1

Greg Rogers
Greg Rogers

Reputation: 36439

Qt has reimplemented most c++ standard library stuff with different interfaces. It looks pretty good, but it can be expensive for the commercially licensed version.

Edit: Qt has since been released under LGPL, which usually makes it possible to use it in commercial product without bying the commercial version (which also still exists).

Upvotes: 1

J. Lurshen
J. Lurshen

Reputation: 39

Sorry, I can't leave a comment, so here's an answer: EASTL is now available at github: https://github.com/paulhodge/EASTL

Upvotes: 3

puetzk
puetzk

Reputation: 10824

MSVC uses a very heavyweight implementation of checked iterators in debug builds, which others have already discussed, so I won't repeat it (but start there)

One other thing that might be of interest to you is that your "debug build" and "release build" probably involves changing (at least) 4 settings which are only loosely related.

  1. Generating a .pdb file (cl /Zi and link /DEBUG), which allows symbolic debugging. You may want to add /OPT:ref to the linker options; the linker drops unreferenced functions when not making a .pdb file, but with /DEBUG mode it keeps them all (since the debug symbols reference them) unless you add this expicitly.
  2. Using a debug version of the C runtime library (probably MSVCR*D.dll, but it depends on what runtime you're using). This boils down to /MT or /MTd (or something else if not using the dll runtime)
  3. Turning off the compiler optimizations (/Od)
  4. setting the preprocessor #defines DEBUG or NDEBUG

These can be switched independently. The first costs nothing in runtime performance, though it adds size. The second makes a number of functions more expensive, but has a huge impact on malloc and free; the debug runtime versions are careful to "poison" the memory they touch with values to make uninitialized data bugs clear. I believe with the MSVCP* STL implementations it also eliminates all the allocation pooling that is usually done, so that leaks show exactly the block you'd think and not some larger chunk of memory that it's been sub-allocating; that means it makes more calls to malloc on top of them being much slower. The third; well, that one does lots of things (this question has some good discussion of the subject). Unfortunately, it's needed if you want single-stepping to work smoothly. The fourth affects lots of libraries in various ways, but most notable it compiles in or eliminates assert() and friends.

So you might consider making a build with some lesser combination of these selections. I make a lot of use of builds that use have symbols (/Zi and link /DEBUG) and asserts (/DDEBUG), but are still optimized (/O1 or /O2 or whatever flags you use) but with stack frame pointers kept for clear backtraces (/Oy-) and using the normal runtime library (/MT). This performs close to my release build and is semi-debuggable (backtraces are fine, single-stepping is a bit wacky at the source level; assembly level works fine of course). You can have however many configurations you want; just clone your release one and turn on whatever parts of the debugging seem useful.

Upvotes: 3

Roger Nelson
Roger Nelson

Reputation: 1912

Checkout Data Structures and Algorithms with Object-Oriented Design Patterns in C++ By Bruno Preiss http://www.brpreiss.com/

Upvotes: 1

Vicent Marti
Vicent Marti

Reputation: 7315

For big, performance critical applications, building your own containers specifically tailored to your needs may be worth the time investment.

I´m talking about real game development here.

Upvotes: 7

Jeff
Jeff

Reputation: 1053

EASTL is a possibility, but still not perfect. Paul Pedriana of Electronic Arts did an investigation of various STL implementations with respect to performance in game applications the summary of which is found here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html

Some of these adjustments to are being reviewed for inclusion in the C++ standard.

And note, even EASTL doesn't optimize for the non-optimized case. I had an excel file w/ some timing a while back but I think I've lost it, but for access it was something like:

       debug   release
STL      100        10
EASTL     10         3
array[i]   3         1

The most success I've had was rolling my own containers. You can get those down to near array[x] performance.

Upvotes: 26

rasmusb
rasmusb

Reputation: 438

My experience is that well designed STL code runs slowly in debug builds because the optimizer is turned off. STL containers emit a lot of calls to constructors and operator= which (if they are light weight) gets inlined/removed in release builds.

Also, Visual C++ 2005 and up has checking enabled for STL in both release and debug builds. It is a huge performance hog for STL-heavy software. It can be disabled by defining _SECURE_SCL=0 for all your compilation units. Please note that having different _SECURE_SCL status in different compilation units will almost certainly lead to disaster.

You could create a third build configuration with checking turned off and use that to debug with performance. I recommend you to keep a debug configuration with checking on though, since it's very helpful to catch erroneous array indices and stuff like that.

Upvotes: 21

Thomas Koschel
Thomas Koschel

Reputation: 3361

What about the ACE library? It's an open-source object-oriented framework for concurrent communication software, but it also has some container classes.

Upvotes: 1

rhinovirus
rhinovirus

Reputation: 203

If your running visual studios you may want to consider the following:

#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0

That's just for iterators, what type of STL operations are you preforming? You may want to look at optimizing your memory operations; ie, using resize() to insert several elements at once instead of using pop/push to insert elements one at a time.

Upvotes: 10

Nemanja Trifunovic
Nemanja Trifunovic

Reputation: 24561

Ultimate++ has its own set of containers - not sure if you can use them separatelly from the rest of the library: http://www.ultimatepp.org/

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308276

Check out EASTL.

Upvotes: 3

Will Dean
Will Dean

Reputation: 39510

If you're using Visual C++, then you should have a look at this:

http://channel9.msdn.com/shows/Going+Deep/STL-Iterator-Debugging-and-Secure-SCL/

and the links from that page, which cover the various costs and options of all the debug-mode checking which the MS/Dinkware STL does.

If you're going to ask such a platform dependent question, it would be a good idea to mention your platform, too...

Upvotes: 4

MarkR
MarkR

Reputation: 63558

STL containers should not run "really slowly" in debug or anywhere else. Perhaps you're misusing them. You're not running against something like ElectricFence or Valgrind in debug are you? They slow anything down that does lots of allocations.

All the containers can use custom allocators, which some people use to improve performance - but I've never needed to use them myself.

Upvotes: 0

Fred Larson
Fred Larson

Reputation: 62083

I'll bet your STL uses a checked implementation for debug. This is probably a good thing, as it will catch iterator overruns and such. If it's that much of a problem for you, there may be a compiler switch to turn it off. Check your docs.

Upvotes: 4

Related Questions