Speed Test: std::Vector vs Array

12
Mar/10
0

Most recently I have been working on a multithreaded ray tracer in order to port it to CUDA so I am not using any recursion. The first step is implementing the ray tracer without using any acceleration structure. So I simply test a ray with all the objects in a scene thus I needed to decide using whether an array or a vector.
As the current code strongly relies on the data structure I am using, I wanted to test the iteration speed of std::vector versus array.

Here is the code I used for testing.

  1.  
  2. #include <iostream>
  3. #include <map>
  4. #include <vector>
  5. #include <array>
  6. #include <stack>
  7. #include <windows.h>
  8. #include <math.h>
  9. typedef DWORD TIME_TYPE;
  10.  
  11.  
  12. #define BEGIN_TIMING(repeat)     TIME_TYPE dwStartTime = timeGetTime();         for(int __i = 0; __i < repeat; __i++){
  13. #define END_TIMING              }; TIME_TYPE __ret = (timeGetTime() – dwStartTime); cout<< __FUNCTION__ << "\t\t: elapsed time =\t"<<__ret<<endl; return __ret;;
  14.  
  15.  
  16. const unsigned int g_uiStartTestSize    = 1000000;
  17. const unsigned int g_uiStartRepeatCount = 1;
  18.  
  19. unsigned int g_uiTestSize       = 0;
  20. unsigned int g_uiRepeatCount = 0;
  21. unsigned int g_uiNumOfTestSteps = 10;
  22. using namespace std;
  23. using std::map;
  24. using std::vector;
  25.  
  26. class ClassA
  27. {
  28. public:
  29.         ClassA(){a=b=c=d=0;};
  30.         ~ClassA(){};
  31.         double a;
  32.         double b;
  33.         double c;
  34.         double d;
  35. };
  36.  
  37.  
  38.  
  39. vector<ClassA*>* classAVector;
  40. ClassA** classAArray;
  41.  
  42. TIME_TYPE testFillInArray()
  43. {
  44.         BEGIN_TIMING(1)
  45.                 classAArray = new ClassA*[g_uiTestSize];
  46.                 for(int i =0; i < g_uiTestSize; i++)
  47.                 {
  48.                         classAArray[i] = new ClassA();
  49.                 }
  50.         END_TIMING
  51. }
  52.  
  53. TIME_TYPE testFillInVector()
  54. {
  55.         BEGIN_TIMING(1)
  56.                 classAVector = new vector<ClassA*>();
  57.                 for(int i =0; i < g_uiTestSize; i++)
  58.                 {
  59.                         classAVector->push_back(new ClassA());
  60.                 }
  61.         END_TIMING
  62. }
  63.  
  64. TIME_TYPE testDestroyArray()
  65. {
  66.         BEGIN_TIMING(1)
  67.                 for (int i = 0; i < g_uiTestSize; i++)
  68.                 {
  69.                         delete classAArray[i];
  70.                 }
  71.                 delete [] classAArray;
  72.         END_TIMING
  73. }
  74.  
  75. TIME_TYPE testDestroyVector()
  76. {
  77.         BEGIN_TIMING(1)
  78.                 for  (int i = 0; i < g_uiTestSize; i++)
  79.                 {
  80.                         delete (*classAVector)[i];
  81.                 }
  82.                 delete classAVector;
  83.  
  84.         END_TIMING
  85. }
  86.  
  87. TIME_TYPE testIterateVector(void)
  88. {
  89.         BEGIN_TIMING(g_uiRepeatCount)
  90.         ClassA *pClassA;
  91.  
  92. /*
  93.         const int sz = classAVector->size();
  94.         for (int i = 0; i < sz; i++)
  95.         {
  96.                 pClassA = (*classAVector)[i];          
  97.                 pClassA->a++;
  98.                 pClassA->b++;
  99.                 pClassA->c++;
  100.                 pClassA->d++;
  101.         }*/
  102.  
  103.  
  104.  
  105.         vector<ClassA*>::iterator it = classAVector->begin();
  106.                 const vector<ClassA*>::iterator endIt = classAVector->end();
  107.                 while(it != endIt)
  108.                 {
  109.                         pClassA = (*it);
  110.                         pClassA->a++;
  111.                         pClassA->b++;
  112.                         pClassA->c++;
  113.                         pClassA->d++;
  114.                         it++;
  115.                 }
  116.  
  117.         END_TIMING
  118. }
  119.  
  120. TIME_TYPE testIterateArray(void)
  121. {
  122.         BEGIN_TIMING(g_uiRepeatCount)
  123.         ClassA *pClassA;
  124.         for (int i =0; i < g_uiTestSize; i++)
  125.         {
  126.                 pClassA = classAArray[i];
  127.                 pClassA->a++;
  128.                 pClassA->b++;
  129.                 pClassA->c++;
  130.                 pClassA->d++;
  131.  
  132.         }
  133.         END_TIMING
  134. }
  135.  
  136. void verify()
  137. {
  138.         cout<<"verifying"<<endl;
  139.         for (int i=0; i < g_uiTestSize; i++)
  140.         {
  141.                 if( (*classAArray[i]).a != classAVector->at(i)->a )
  142.                 {
  143.                         cout << "error!:" << i <<endl;
  144.                 }
  145.         }
  146. }
  147.  
  148. TIME_TYPE testAll()
  149. {
  150.         BEGIN_TIMING(1)
  151.                 g_uiTestSize = g_uiStartTestSize;
  152.                 for (int i =1; i <= g_uiNumOfTestSteps; i++)
  153.                 {
  154.                         g_uiRepeatCount = g_uiStartRepeatCount * i;
  155.                         cout<< "repeat count =\t\t"<<g_uiRepeatCount<<endl;
  156.                         cout<< "test size    =\t\t"<<g_uiTestSize<<endl;
  157.                         testFillInArray();
  158.                         testFillInVector();
  159.                         testIterateArray();
  160.                         testIterateVector();
  161.                         testDestroyArray();
  162.                         testDestroyVector();
  163.                         cout<<"———————————————"<<endl;
  164.                 }
  165.                 g_uiRepeatCount = g_uiStartRepeatCount;
  166.                 for (int i =1; i <= g_uiNumOfTestSteps; i++)
  167.                 {
  168.                         g_uiTestSize = g_uiStartTestSize * i;
  169.                         cout<< "repeat count =\t"<<g_uiRepeatCount<<endl;
  170.                         cout<< "test size    =\t"<<g_uiTestSize<<endl;
  171.                         testFillInArray();
  172.                         testFillInVector();
  173.                         testIterateArray();
  174.                         testIterateVector();
  175.                         testDestroyArray();
  176.                         testDestroyVector();
  177.                         cout<<"———————————————"<<endl;
  178.                 }
  179.  
  180.         END_TIMING
  181.  
  182. }
  183.  
  184.  
  185.  
  186.  
  187. int main(void)
  188. {
  189.         testAll();
  190.         return 0;
  191. }
  192.  
  193.  

Here is the code to download

Results
Results are striking indeed. If you compiling the code in Release mode without any run-time error checking and disabled exection support iterating a Vector by using std::vector<>::iterator is almost as fast as using array.

However testing them on debug mode shows the difference, iteration time is terribly slow on std::vector ; about 60 times slower.

Conclusion
std::vector is almost as fast as using a static array on release mode (using Visual Studio 2008) but terribly slow on debug mode. So if your code is running slow on the debug mode, don’t give up std::vector and give a go on the release mode.

Tagged as: