Re: std::vector slow?
On Thu, 8 Nov 2007 03:14:33 CST, David Klein wrote:
I wrote a simple template class Vec and when I compile with
optimization under Visual Studio 2005, std::vector takes 56% more
time. I would have thought that std::vector is much more optimized
than anything I could roll myself. Am I mis-using std::vector somehow?
Or is it really that inefficient?
I tested your code, here are my results. After the results comes
my explanation for the difference. (Use a monospace font to view.)
Compiler: GCC (plain) ICC GCC (vectorize)
std::vector<> 1.31 .. 1.32 1.05 .. 1.09 0.90 .. 0.92
vec<> 1.20 .. 1.16 0.55 .. 0.56 0.83 .. 0.84
The compiler flags for GCC were -mtune=native -O3 -finline and
for ICC, -fast. In GCC's vectorize test I used -ftree-vectorize.
The differences between the vectors.
std::vector<> contains a capacity and a length, whereas yours contains
only the length. Also, yours is not copy-safe, whereas std::vector<>
can be safely assigned to and copy-constructed. However, these
differences are merely superficial, and do not significantly
contribute to the results.
The significant difference is that your vec<> does an array new[]
whereas std::vector<> does a raw allocation combined with explicit
constructing.
The difference between these two is, that std::vector<int> is
preinitialized to zero, whereas new int[] returns an array of
ints that are not initialized to any particular value.
You notice a performance difference only, because your test
datatype is int, where the semantics differ.
If your datatype was, say, std::string, you'd notice a neglible
difference if any at all.
In fact, I tested by changing the datatype into std::string
and lowering n into 2<<12, and I'm now getting 2.25 seconds
for both vectors on GCC, 2.46 on ICC.
If you are worried about the performance of std::vector<> when
used with non-POD types, then you cannot use std::vector<> in
those cases.
Your code still quoted here for the benefit of follow-up posters.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
template <class T> class Vec
{
public:
Vec(void)
{
mPtr = NULL;
mNElem = 0;
}
Vec(int size) : mNElem(0), mPtr(NULL)
{
if (size < 0) throw "Size < 0\n";
if (size > 0)
{
mPtr = new T [size];
if (mPtr == NULL)throw "Vec allocation failed\n";
mNElem = size;
}
}
~Vec(void)
{
if (mPtr) delete [] mPtr;
mPtr = NULL;
mNElem = 0;
}
int size(void) const { return mNElem; }
T &operator[](const int i) const { return mPtr[i];}
private:
T *mPtr;
int mNElem;
};
using std::vector;
const static int n = 2<<16;
const static int times = 2<<10;
int main(int argc, char* argv[])
{
double s;
clock_t start, end;
start = clock();
for (int j=0; j<times; j++) {
s = 0;
vector<int> y(n);
for (int i=0; i<n; i++) {
y[i] = i;
}
for (int i=0; i<n; i++) {
if (y[i]>s) s=y[i];
}
}
end = clock();
printf("s, Time: %g, %g\n", s, (end-start)/(double)CLOCKS_PER_SEC);
start = clock();
for (int j=0; j<times; j++) {
s = 0;
Vec<int> x(n);
for (int i=0; i<n; i++) {
x[i] = i;
}
for (int i=0; i<n; i++) {
if (x[i]>s) s=x[i];
}
}
end = clock();
printf("s, Time: %g, %g\n", s, (end-start)/(double)CLOCKS_PER_SEC);
printf("Press Enter to continue\n");
getchar();
return 0;
}
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
: Try to be as precise as can be and no one will comprehend what you mean.
: Say nothing, and everybody will understand.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]