Our coding guidelines prefer const_iterator
, because they are a little faster compared to a normal iterator
. It seems like the compiler optimizes t
They are for non-trivial containers/iterators. Get your habits straight and you won't lose performance when it does matter.
Also, there are several reasons to prefer const_iterator, no matter what:
begin()
to flag data as dirty (i.e. OpenSG) and will send it to other threads/over-network on sync, so there it has real performance implications.As an example of the last point above, here's an excerpt from qmap.h in Qt:
inline iterator begin() { detach(); return iterator(e->forward[0]); }
inline const_iterator begin() const { return const_iterator(e->forward[0]); }
Even if iterator and const_iterator are practically equivalent (except for the const
),
detach()
creates a new copy of the data if there are two or more objects using it. This is completely useless if you're just going to read the data, which you indicate by using const_iterator
.
Of course, there are data points in the other direction:
If nothing else, a const_iterator
reads better, since it tells anyone reading the code "I'm just iterating over this container, not messing with the objects contained".
That's a great big win, never mind any performance differences.
when you benchmark any of this, make sure to use an appropriate optimization level -- you'll get wildly different timings using "-O0" versus "-O" and such.
I my experience, the compiler does not do any measureable optimization when using const iterators. Althought the statement "it could" is true and references are not defined to be pointers in the standard.
However, you can have two references to the same object, so one can be const, one non-const. Then, I guess the answers in this thread on restrict pointers apply: The compiler cannot know whether the object is changed by another thread, for example, or by some interrupt handling code.
The guideline we use is:
Always prefer const over non-const
If you tend to use const object, you get used to using only constant operations on the objects you get and that is as much as using const_iterator as much as possible.
Constness has a viral property. Once you get to use it, it propagates to all your code. Your non-mutating methods become constant, and that requires using only constant operations on the attributes, and passing constant references around, that itself forces only constant operations...
To me, the performance advantage of using constant iterators over non constant iterators (if any at all) is much less important than the improvement in the code itself. Operations meant (designed) to be non-mutating are constant.