Aspects of operator[] vs at()
In order to bump the default memory safety of C++ the committee has decided to harden the STL with adding bounds checking to operator[]. This is redundant since bounds checking is already present through function 'at()'. Instead a safety profile could promote 'at()' and issue a warning for the use of operator[].
This decision has also consequences for performance. If we compare current operator[] which has no bounds checking with 'at()' with bounds checking it is 5 times slower. Consider the following two functions:
int g_iTemp = 0;void PrfStlVectorIteratorIndex(const std::vector<int>& rv)
{
int nTemp = 0; const size_t nLoop = rv.size();
for (size_t n = 0; n != nLoop; ++n)
{
nTemp += rv[n];
}
g_iTemp = nTemp;
} void PrfStlVectorIteratorIndex(const std::vector<int>& rv)
{
int nTemp = 0; const size_t nLoop = rv.size(); for (size_t n = 0; n != nLoop; ++n1)
{
nTemp += rv.at(n);
}
g_iTemp = nTemp;
} The results for a certain test with VS2022 17.14.23 with /O2:
Function # Total(s)
PrfStlVectorIteratorIndex 1 0.149972
PrfStlVectorIteratorIndexAt 1 0.727781 The function using 'at()' is 5 times slower. Spying the assembly it seems that MSVC uses SIMD instructions in case of operator[] but it cannot use them with 'at()'.
Conclusion
This is a significant difference. It makes one wonder why the C++ committee took the decision so lightly to tax every invocation of operator[]. Especially since a major use case for operator[] is to use it in a loop as above where there is no danger of going out of bounds. Their argument is that it costed only 0.3% extra performance which clearly contradicts above numbers. Also they stated that on certain code bases it revealed thousand extra bugs. Not sure what that code base is. For decades we use Visual Studio with Microsoft's STL which has the extra checking turned on in debug mode and it never fires these asserts when testing debug builds (which is what programmers do all the time). If it would fire you found a bug and repair it. Let users who value safety over performance use the 'at()' variants but leave the operator[] alone.
No comments:
Post a Comment