std::vector vs. C-style arrays
I hope that the stl gurus can help me with this...
Consider the following: In my current project, a team member implemented code such as the following:
Code:
int* m_timeArray;
string* m_nameArray;
double* m_valueArray;
// Dynamically allocate space for the arrays here...
for(int i=0; i < numElements; i++)
{
m_timeArray[i] = someTime;
m_nameArray[i] = someName;
m_valueArray[i] = someValue;
}
As these C-style arrays are actually representing an array of objects (each consisting of a time, a name and a value, in this simplified example), I suggested to - create a class which has time, name and value as members, and
- use a std::vector instead of a C array.
Something along the lines of:
Code:
class Element
{
public:
Element(int time, const char* pName, double value);
virtual ~Element();
private:
int m_time;
string m_name;
double m_value;
};
vector<Element> elements;
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?
Re: std::vector vs. C-style arrays
Quote:
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.
Quote:
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.
Quote:
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 =?
Code:
for(int i=0; i < numElements; i++)
{
m_timeArray[i] = someTime;
//...
}
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.
Regards,
Paul McKenzie
Re: Re: std::vector vs. C-style arrays
Quote:
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.