If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Now this is a very performance critical part of the code, and the other team member (which is a hardcore C-programmer and performance fetishist anyway, who mistrusts stl and C++ in general) argued that it wouldn't be possible with this design to add elements to the array with the same efficiency. More specifically, code like

Code:

elements.push_back(Element(someTime, someName, someValue));

will of course create a temporary Element object and invoke Element's default copy constructor, which is obviously more costly than the C code. However, I made two bold statements saying that

when switching from a C array to std::vector, very little changes will be necessary to the existing code (which is not true, as I can't add elements to the array with something like elements[i] = ..., but I will have to use push_back - right?)

That it is possible to use a std::vector of elements with the same efficiency as using multiple C arrays (like in the original code).

Here I'm stuck - it seems that I can't add elements to the vector without creating a temporary object, and therefore effectively copying the data twice. Any ideas?

Well...I am a little bit in a hurry here...so I will not go into all of the details now (pretty sure until I am back there have been others already providing more information).

In general, using any of the STL classes does not mean necessarely that the resulting code will perform slower than the old one. And even with 'vector' it is most of the time the other way round. One common mistake is to actually compare debug versions instead of release ones.

Furthermore, if e.g. a 'vector' performs much slower in a release build, then it is most-likely due to the fact, that the implementation (how the 'vector' is being used not the 'vector' implementation itself) is 'bad'. For example in your case, you should already reserve enough memory (-> 'numElements') for the 'vector' up-front, so that no additional memory allocation is necessary while doing a 'push_back()'.

For additional information you might want to take a look at the following introduction to the 'vector' class...

Re: std::vector vs. C-style arrays

Originally posted by etaoin
Now this is a very performance critical part of the code, and the other team member (which is a hardcore C-programmer and performance fetishist anyway, who mistrusts stl and C++ in general) argued that it wouldn't be possible with this design to add elements to the array with the same efficiency. More specifically, code like

Code:

elements.push_back(Element(someTime, someName, someValue));

will of course create a temporary Element object and invoke Element's default copy constructor, which is obviously more costly than the C code.

Your friend will be surprised as to which is faster.

However, I made two bold statements saying that[list=1][*]when switching from a C array to std::vector, very little changes will be necessary to the existing code (which is not true, as I can't add elements to the array with something like elements[i] = ..., but I will have to use push_back - right?)[*]

You can size the vector before adding any elements, and then use operator [] to fill the vector, or you can use push_back.

That it is possible to use a std::vector of elements with the same efficiency as using multiple C arrays (like in the original code).

Yes, if not more efficient. If this isn't the case, your implementation is bad or your compiler does not aggressively do optimizations.

One trick you can show your friend -- the reserve() function preallocates memory up front, so that vector doesn't have to do allocations each time you call push_back(). So if your friend is showing you code that calls push_back in a loop 10,000 times and says "ha ha, you lose", just add a call to reserve() before you call the loop to the push_backs, and watch them scramble to explain why all of a sudden, the vector has caught up, if not beaten their code.

As far as copying the data, isn't that what is being done in your friend's code when he invokes operator =?

You are making a copy of someTime and storing it in m_timeArray. If not, then your friend is storing pointers, and is not comparing apples with apples. For a fair comparison, the vector should also store pointers.

Originally posted by Andreas Masur
In general, using any of the STL classes does not mean necessarely that the resulting code will perform slower than the old one. And even with 'vector' it is most of the time the other way round. One common mistake is to actually compare debug versions instead of release ones.

Furthermore, if e.g. a 'vector' performs much slower in a release build, then it is most-likely due to the fact, that the implementation (how the 'vector' is being used not the 'vector' implementation itself) is 'bad'. For example in your case, you should already reserve enough memory (-> 'numElements') for the 'vector' up-front, so that no additional memory allocation is necessary while doing a 'push_back()'.

Andreas, thanks for your reply.

I agree with what you say, and I already knew that. Maybe I didn't make my point clear enough, but my problem is not about the performance of a dynamically growing vector - it is obvious that adding elements beyond the current size of the vector will lead to a reallocation (which would be necessary with a C-array anyway).

Even when we reduce the problem to a vector of a pre-determined size - my question is, how can I initialize the elements without invoking the copy constructor and creating a temporary element? With a C array, we can do the following (assuming, for simplicity, that the members of Element were public):

Re: Re: std::vector vs. C-style arrays

Originally posted by Paul McKenzie
One trick you can show your friend -- the reserve() function preallocates memory up front, so that vector doesn't have to do allocations each time you call push_back().

Paul, thanks for your ideas too. However, as said in my reply to Andreas' post, the problem is not the dynamically growing array - I know about reserve() and how to use it. It is actually about how to initialize the vector with elements without creating temporary objects.

From my understanding, as long as you vector::reserve(), the overhead for vector::push_back() is the same, if not faster, as assigning value into an array. When we vector::push_back(), the copy ctor is invoked whereas the operator=() is used for assignment in array. Since you are storing value in vector and array, I don't see any reason why temporary object is created. You can prove this by providing your copy ctor and operator=() in your class and track the number of time copy ctor and operator=() is invoked for each case. In fact, for the same no. of vector::push() and assignment in array, the no. of call to copy ctor is exactly the same as that of operator().

This will simply assign the values once to each element in the array, leading to no overhead as compared to the original code.

The operator = is invoked for the m_time, m_name, and m_value types. It still is making a copy (actually an assignment, but in effect, a copy). As Philip shows, the operator = is not so benign in C++ as it is in C.

Even when we reduce the problem to a vector of a pre-determined size - my question is, how can I initialize the elements without invoking the copy constructor and creating a temporary element? With a C array, we can do the following (assuming, for simplicity, that the members of Element were public):

* The Perfect Platform for Game Developers: Android
Developing rich, high performance Android games from the ground up is a daunting task. Intel has provided Android developers with a number of tools that can be leveraged by Android game developers.

* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.