C++ has a number of solutions for collections/arrays, including arrays inherited from C, STL collections such as vector, and non-standard yet widely adopted solutions such as Boost’s scoped_array and shared_array.
STL’s vector is the preferred option for collections that need to dynamically resize. But what about fixed size arrays?
If you only need a fixed size array of, say, integers, and performance is critical then which solution is best?
This was the question I was faced with earlier, so I did some profiling tests. The following graph illustrates the results:

Tests were performed with MSVC 9 (Visual Studio 2008, with VC Feature Pack) and Boost version 1.34.1 on an Intel Q6600 CPU with Windows Vista SP1. See below for test details.
Interpretation of Results
Boost’s scoped_array and shared_array perform just as fast as a C-array solution. The tiny variance in results is likely to be memory/operating system factors rather than the solution itself.
Boost’s solutions should be preferred over C arrays since they minimise potential memory leaks.
As expected, vector suffered from it’s power; it’s designed for a wide variety of use cases, including the ability to dynamically resize itself, and in this scenario that extra power added some overhead. Note, however, that the vector test case did not do any dynamic resizing; the vector was manually resized/reserved to the required size before populating it with values.
Test Details
The following tests were performed on a C array, scoped_array, shared_array and vector:
- Create 3 arrays of integers (named source1, source2, dest) with a size of 720 x 576 x 4. This size represents a typical RGBA video image.
- Populate source1 and source2 arrays with random values.
- Perform the following tests:
for (size_t i = 0; i < arraySize; ++i)
{
dest[i] = source1[i] + source2[i];
}
and:
for (size_t i = 0; i < arraySize; ++i)
{
int rndSource1 = rand() % arraySize;
int rndSource2 = rand() % arraySize;
dest[i] = source1[rndSource1] + source2[rndSource2];
}
Then finally, if necessary, destroy the arrays.
As can be observed, the test cases are quite basic and focus on accessing the array elements. The first loop accesses the elements in sequential order (which will take advantage of CPU cache lines), whereas the second loop accesses the elements somewhat randomly.
These test cases fulfilled the requirements that I wanted to profile, but performance results may differ with other test cases.
The test cases were repeated 10 times for each array solution, with timing done around the entire operation by using the QueryPerformanceFrequency and QueryPerformanceCounter Windows APIs.
The order of the array tests was changed as well, in case subsequent arrays benefited from previous execution.
First run:
- scoped_array
- shared_array
- C array
- vector
Second run:
- vector
- C array
- shared_array
- scoped_array
Third run:
- vector
- scoped_array
- C array
- shared_array