views:

363

answers:

7

I use vectors, lists, strings and wstrings obsessively in my code. Are there any catch 22s involved that should make me more interested in using arrays from time to time, chars and wchars instead?

Basically, if working in an environment which supports the standard template library is there any case using the primitive types is actually better?

A: 

If you don't need real time responses, stick with your approach. They are safer than chars.

Burkhard
+2  A: 

One problem is the overhead when accessing elements. Even with vector and string when you access an element by index you need to first retrieve the buffer address, then add the offset (you don't do it manually, but the compiler emits such code). With raw array you already have the buffer address. This extra indirection can lead to significant overhead in certain cases and is subject to profiling when you want to improve performance.

sharptooth
The trick here would be not to use `operator[]` so much, but instead work with iterators. Quite often they map to char * into the underlying character array.
True, but this should be investigated for the STL implementation used - it may work this way or another.
sharptooth
A: 

You can occasionally encounter scenarios where you'll get better performance or memory usage from doing some stuff yourself (example, std::string typically has about 24 bytes of overhead, 12 bytes for the pointers in the std::string itself, and a header block on its dynamically allocated piece).

I have worked on projects where converting from std::string to const char* saved noticeable memory (10's of MB). I don't believe these projects are what you would call typical.

Oh, using STL will hurt your compile times, and at some point that may be an issue. When your project results in over a GB of object files being passed to the linker, you might want to consider how much of that is template bloat.

Don Neufeld
There are plenty of methods for dealing with slow compile times. Avoiding using STL for this reason would be my absolute last resort.
James Hopkin
+3  A: 

I would stick to STL classes (vectors, strings, etc). They are safer, easier to use, more productive, with less probability to have memory leaks and, AFAIK, they make some additional, run-time checking of boundaries, at least at DEBUG time (Visual C++).

Then, measure the performance. If you identify the bottleneck(s) is on STL classes, then move to C style strings and arrays usage.

From my experience, the chances to have the bottleneck on vector or string usage are very low.

Cătălin Pitiș
+1 Exactly what I would have answered :)
soulmerge
A: 

I've worked on several projects where the memory overhead for strings has become problematic.

It's worth considering in advance how your application needs to scale. If you need to be storing an unbounded number of strings, using const char*s into a globally managed string table can save you huge amounts of memory.

But generally, definitely use STL types unless there's a very good reason to do otherwise.

James Hopkin
+3  A: 

For 99% of the time and for 99% of Standard Library implementations, you will find that std::vectors will be fast enough, and the convenience and safety you get from using them will more than outweigh any small performance cost.

For those very rare cases when you really need bare-metal code, you can treat a vector like a C-style array:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

The C++ standard guarantees that vectors are allocated contiguously, so this is guaranteed to work.

Regarding strings, the convenience factor becomes almnost overwhelming, and the performance issues tend to go away. If you go beack to C-style strings, you are also going back to the use of functions like strlen(), which are inherently very inefficent themselves.

As for lists, you should think twice, and probably thrice, before using them at all, whether your own implementation or the standard. The vast majority of computing problems are better solved using a vector/array. The reason lists appear so often in the literature is to a large part because they are a convenient data structure for textbook and training course writers to use to explain pointers and dynamic allocation in one go. I speak here as an ex training course writer.

anon
I don't see how using vectors would work when trying to sort, surely lists are more efficient for these things? Or would it sitll be better to use multiple vectors when sorting instead of a single list?
meds
Vectors may or may not be nore efficient when sorting. Sorting a vector of of ints will be faster than sorting a list of ints, becuase the vecrtor requires only one fast exchange operation whereas the list requires several pointer adjustments. For non-POD objects, a list is probably going to be faster. But sorting is quite a rare thing to do in real code.
anon
A: 

I believe the default memory allocation technique is a buffer for vectors and strings is one that allocates double the amount of memory each time the currently allocated memory gets used up. This can be wasteful. You can provide a custom allocator of course...

The other thing to consider is stack vs. heap. Staticly sized arrays and strings can sit on the stack, or at least the compiler handles the memory management for you. Newer compilers will handle dynamically sized arrays for you too if they provide the relevant C99/C++0x feature. Vectors and strings will always use the heap, and this can introduce performance issues if you have really tight constraints.

As a rule of thumb use whats already there unless it hurts your project with its speed/memory overhead... you'll probably find that for 99% of stuff the STL provided classes save you time and effort with little to no impact on your applications performance. (i.e. "avoid premature optimisation")

jheriko
What makes you think that C++0x will suopport dynamic arrays?
anon