问题
The result of a discussion with a colleague I ended up writing benchmarks to test std::vector
vs raw dynamically allocated arrays, and ended up with a surprise.
My tests are as follows:
#include "testconsts.h" // defines NUM_INTS across all tests
#include <vector>
int main()
{
const int numInts = NUM_INTS;
std::vector<int> intVector( numInts );
int * const intArray = new int[ numInts ];
++intVector[0]; // force access to affect optimization
++intArray[0]; // force access to affect optimization
for( int i = 0; i < numInts; ++i )
{
++intArray[i];
}
delete[] intArray;
return 0;
}
and:
#include "testconsts.h" // defines NUM_INTS across all tests
#include <vector>
int main()
{
const int numInts = NUM_INTS;
std::vector<int> intVector( numInts );
int * intArray = new int[ numInts ];
++intArray[0]; // force access to affect optimization
++intVector[0]; // force access to affect optimization
for( int i = 0; i < numInts; ++i )
{
++intVector[i];
}
delete[] intArray;
return 0;
}
They are compiled with g++ -O3 with gcc 4.4.3
The results of multiple runs of benchmarking using time
are similar to:
Array:
real 0m0.757s
user 0m0.176s
sys 0m0.588s
Vector:
real 0m0.572s
user 0m0.268s
sys 0m0.304s
Three things are clear:
- Array is faster in user time
- Vector is faster less system time
- Over all vector won this fight
The question is "why?".
The system time issue I'm guessing must have to do with page faults, but I can't describe for myself exactly why one would have significantly more page faults.
As for the user time issue, it's less interesting to me, but I'm still curious of opinions on that as well. I had imagined it had something to do with initialization, though I'm not passing an initialization value to the vector constructor so I don't know.
回答1:
The difference is not in the performance of the vector compared to the dynamic array, but in the number of accesses to memory that you perform.
Effectively, in the vector test you are re-accessing cached memory, while in the array version you don't. You pay the price of caching the vector version in either case.
In the vector test, you allocate the dynamic memory for the array but leave it untouched, with the memory never being touched there are no page faults due to that operation. The vector is created, initialized and then the second pass will be accessing already cached data (if the size fits the cache, if it does not, it will not be in cache, but the same cost will be incurred in both versions).
On the other hand when testing the array, the vector constructor initializes the elements, and that means that in the case were you are trying to profile the behavior of the array, the vector contents are walked over and the array elements are walked over. Double the number of memory accesses, page faults and memory used by the application.
You can try modifying the code so that the dynamic allocation is performed like this:
int * intArray = new int[ numInts ](); // note extra ()
Which will value-initialize the whole array, or you initialize the array contents else how. The results of running that modified version of the test should be similar.
回答2:
Have you run the test more than once? Benchmarking is a hard process, and has to rely on averages to get any kind of meaningful result; it's possible that at the time you were running your array benchmark a few CPU cycles were dedicated to something else, slowing it down. I would expect that given enough results they would be similar, as std::vector
is written with a C-style array at it's core.
来源:https://stackoverflow.com/questions/6823396/why-might-stdvector-be-faster-than-a-raw-dynamically-allocated-array