In C++, would it be better (performance-wise) to iterate through elements in an array
or vector
using the array.at(i)
function or by using array[i]
? Is one more efficient than the other?
-
6`at` performs bounds checking, and `operator[]` does not. So the former does strictly more work than the latter. – Kerrek SB Mar 01 '16 at 11:41
-
2Possible duplicate of [C++ Vector at/\[\] operator speed](http://stackoverflow.com/questions/2578638/c-vector-at-operator-speed) – Michael Mar 01 '16 at 11:45
-
Neither one of those member function iterates through the array. They provide indexed access to one element. – Pete Becker Mar 01 '16 at 13:19
-
1@Pete OP isn’t saying that the functions iterate through the array … – Konrad Rudolph Mar 01 '16 at 13:53
3 Answers
The at()
method performs bounds checking on the passed index, operator[]
doesn't.
So using at()
may be slower from a performance perspective if you have lots of element accesses.
(I recall I did some tests with big matrices in an older version of MSVC, and there was a difference between accessing each item with and without bounds checking. As usual, when in doubt, measure.)
Note also that in some implementations like MSVC's one, operator[]
performs bounds checking in debug builds.

- 41,637
- 14
- 86
- 162
-
1Regarding your last sentence: More precisely, it's either the `/MDd` or the `/MTd` compiler flag which enables the checks. – Christian Hackl Mar 01 '16 at 12:00
-
1More accurately, `operator[]` doesn't *have* to perform bounds checking. So it is implementation dependent whether it does or not. Typically, optimized builds do not, unoptimized builds often do. – Martin Bonner supports Monica Mar 01 '16 at 12:57
-
@Martin Is that true? I’ve never heard of an optimiser that chooses different code paths. *Debug* builds often include checks, true. But how do you even test for the presence of an optimiser in code? – Konrad Rudolph Mar 01 '16 at 13:54
-
@KonradRudolph: In my mind, "an optimized build" is not quite the same as "an optimizer". An optimized build is likely to run the optimizer, but it will probably also set #define flags to disable time-consuming checks. – Martin Bonner supports Monica Mar 01 '16 at 13:56
-
1@Martin Alright, but what does this mean in the context of `std::vector::operator[]` then? What are these flags? Or are you talking about debug builds? – Konrad Rudolph Mar 01 '16 at 14:09
-
@KonradRudolph: I can imagine a bounds check that's labelled `Unreachable` using an implementation `pragma`. The optimizer, seeing that label, would remove the branch, whereas the debug build would simply execute it as written. This would be easier than a whole bunch of `#ifdef`'s. – MSalters Mar 01 '16 at 14:49
For std::vector::at
or std::array::at
,
Returns a reference to the element at specified location pos, with bounds checking.
And for std::vector::operator[]
or std::array::operator[]
,
Returns a reference to the element at specified location pos. No bounds checking is performed.
So in theory, operator[]
would be more efficient. In the actual situation, you might measure.

- 169,198
- 16
- 310
- 405
If the code is truly iterating through the array, then the iteration code is responsible for ensuring that accesses are not out of bounds. For example:
for (int i = 0; i < my_vec.size(); ++i)
std::cout << my_vec[i] << '\n';
There's no need to build in extra overhead by checking whether i
is out of bounds. It won't be.

- 74,985
- 8
- 76
- 165