Quote:
Well still, how many times do we need to run in debug mode? You still need fast enough debug code.
The checks can be disabled in debug mode if you like.
Ok, lets look at the assembly. Here is the source I used:
#include <vector>#include <cstdio>#include <windows.h>using namespace std;const unsigned int XSIZE = 10000000;int main(){ vector<int> vecNumbers; int arrayNumbers[XSIZE]; vecNumbers.reserve(10000000); for(int i = 0; i < XSIZE; i++) { vecNumbers.push_back(0); arrayNumbers = 0; } DWORD start_time = GetTickCount(); for(int i = 0; i < XSIZE;i++) { arrayNumbers++; } DWORD elapsed = GetTickCount() - start_time; printf("array: %d\n", elapsed); start_time = GetTickCount(); for(int i = 0; i < XSIZE;i++) { vecNumbers++; } elapsed = GetTickCount() - start_time; printf("vector: %d\n", elapsed); system("pause"); return 0;}
Assembler output:
; 19 : ; 20 : DWORD start_time = GetTickCount(); mov edi, DWORD PTR __imp__GetTickCount@0 call edi mov ebx, eax; 21 : for(int i = 0; i < XSIZE;i++) xor eax, eax npad 4$LL6@main:; 22 : {; 23 : arrayNumbers++; inc DWORD PTR _arrayNumbers$[esp+eax*4+40000056] inc eax cmp eax, 10000000 ; 00989680H jb SHORT $LL6@main; 24 : }; 25 : DWORD elapsed = GetTickCount() - start_time; call edi sub eax, ebx; 26 : printf("array: %d\n", elapsed); push eax push OFFSET $SG-11 call _printf add esp, 8; 27 : ; 28 : start_time = GetTickCount(); call edi mov ebx, eax; 29 : for(int i = 0; i < XSIZE;i++) xor eax, eax$LL3@main:; 30 : {; 31 : vecNumbers++; inc DWORD PTR [esi+eax*4] inc eax cmp eax, 10000000 ; 00989680H jb SHORT $LL3@main; 32 : }; 33 : elapsed = GetTickCount() - start_time; call edi sub eax, ebx; 34 : printf("vector: %d\n", elapsed); push eax push OFFSET $SG-12 call _printf; 35 : ; 36 : system("pause"); push OFFSET $SG-13 call _system add esp, 12 ; 0000000cH
To simplify, I replaced ostream with printf (ostream adds lots of gunk to asm output). I also stack allocated both objects (I had to increase the stack size to accomodate the large array).
Just to highlight, for an array:
; 23 : arrayNumbers++; inc DWORD PTR _arrayNumbers$[esp+eax*4+40000056] inc eax cmp eax, 10000000 ; 00989680H jb SHORT $LL6@main; 24 : }
Whereas for a vector:
; 31 : vecNumbers++; inc DWORD PTR [esi+eax*4] inc eax cmp eax, 10000000 ; 00989680H jb SHORT $LL3@main
I'm no assembly wizard, but this seems pretty comparable. On my machine I get near identical times, maybe a millisecond favouring one over the other, mine runs in ~16 milliseconds which is too close to the scheduler quantum to be a good measurement.
Upping the size by 10 and looping 10 times shows that the skew is slight in each direction, sometimes favouring vector and other times favouring the array (here both stack and a global array were used, out of curiousity):
Quote:
array: 202 <-- winner
vector: 219
static array: 405
array: 250
vector: 249
static array: 234 <-- winner
array: 219 <-- winner
vector: 296
static array: 296
array: 297
vector: 218 <-- winner
static array: 219
array: 203
vector: 187 <-- winner
static array: 219
array: 202
vector: 188 <-- winner
static array: 202
array: 219
vector: 203
static array: 202 <-- winner
array: 203
vector: 187 <-- winner
static array: 203
array: 203
vector: 202 <-- winner
static array: 203
array: 187 <-- winner (joint)
vector: 187 <-- winner (joint)
static array: 219
In the above run, there is a good mix of winners, the differences more likely due to external issues such as the cache or external processes than any intristic benefit of one technique over the other.
The source for that last test is (aside from the "winner" annotations):
#include <vector>#include <cstdio>#include <windows.h>using namespace std;const unsigned int XSIZE = 100000000;int staticArray[XSIZE];int main(){ vector<int> vecNumbers(XSIZE, 0); int arrayNumbers[XSIZE] = {}; DWORD start_time, elapsed; for(int j = 0 ; j < 10 ; ++j) { start_time = GetTickCount(); for(int i = 0; i < XSIZE;i++) { arrayNumbers++; } elapsed = GetTickCount() - start_time; printf("array: %d\n", elapsed); start_time = GetTickCount(); for(int i = 0; i < XSIZE;i++) { vecNumbers++; } elapsed = GetTickCount() - start_time; printf("vector: %d\n", elapsed); start_time = GetTickCount(); for(int i = 0; i < XSIZE;i++) { staticArray++; } elapsed = GetTickCount() - start_time; printf("static array: %d\n", elapsed); } system("pause"); return 0;}
Again: stack size is increased to handle the insane array.
My conclusion: bullshit