C++ Vector at/[] operator speed - c++

In order to give functions the option to modify the vector I can't do
curr = myvec.at( i );
doThis( curr );
doThat( curr );
doStuffWith( curr );
But I have to do:
doThis( myvec.at( i ) );
doThat( myvec.at( i ) );
doStuffWith( myvec.at( i ) );
(as the answers of my other question pointed out)
I'm going to make a hell lot of calls to myvec.at() then. How fast is it, compared to the first example using a variable to store the result?
Is there a different option for me? Can I somehow use pointers?
When it's getting serious there will be thousands of calls to myvec.at() per second. So every little performance-eater is important.

You can use a reference:
int &curr = myvec.at(i);
// do stuff with curr
The at member function does bounds checking to make sure the argument is within the size of the vector. Profiling is only way to know exactly how much slower it is compared to operator[]. Using a reference here allows you to do the lookup once and then use the result in other places. And you can make it a reference-to-const if you want to protect yourself from accidentally changing the value.

From my own tests with similar code (compiled under gcc and Linux), operator[] can be noticeably faster than at, not because of the bounds checking, but because of the overhead of exception handling. Replacing at (which throws an exception on out-of-bounds) with my own bounds checking that raised an assert on out-of-bounds gave a measurable improvement.
Using a reference, as Kristo said, lets you only incur the bounds checking overhead once.
Ignoring bounds checking and exception handling overhead, both operator[] and at should be optimized to equivalent to direct array access or direct access via pointer.
As Chris Becke said, though, there's no substitute for profiling.

When performance is an issue, there is no substitute for profiling. The optimization capabilities of compilers change from version to version, and tiny, insignificant alterations to source code can dramatically change the resulting performace.
No one can answer this question but yourself: Create a test harness, and throw several algorithms at it and see what you get.
ps. if performance really is an issue, well, i got a factor 10 speed increase out of a png decoder by removing the vectors and replacing them with raw arrays. Again, this was for Visual Studio 6. I am not claiming that a raw array substitution will give you a factor 10 improvement, but it is something to try.

The reason the first doesn't work is that you're not setting a pointer or iterator to the address of the ith variable. Instead you're setting curr equal to the value of the ith variable and then modifying curr. I'm assuming that doThis and doThat are references.
Do this:
MyObject& curr = myvec.at( i );

Operator[] might be faster than at, because it isn't required to do bounds checking.
You can make curr a reference to do what you want.
MyClass & curr = myvec.at(i);
You might also do some benchmarking before getting worried. Modern processors can handle thousands of operations per second quite easily.

Options that I see, in roughly inverse order of preference:
Store pointers in your container instead of the actual objects. This may be advisable anyway, if the objects are complex enough that copying them around is problematic.
Use the indexing operator [] instead of at().
Just call at() once, and save it into a reference (see Kristo's answer above).
Forget about it until you actually have a problem with excessive runtime. If that happens, profile your code first to make sure the bottleneck is here, and only then worry about doing one of the above to speed things up.
Honestly, what you should do is play with the four different approaches, and just use the one that produces the easiest to understand code. In most cases we are happy to sacrifice a few machine cycles for code that is easier for human beings to maintain.

The complexity of at() is constant, i.e., in practice this means that it must be designed to not have any relevant performance penalty.
You can use [], which is also constant complexity, but does not check bounds. This would be equivalent to using pointer arithmetic and, thus, potentially a bit faster than the former.
In any case, vector is specifically designed for constant performance access to any of its elements. So this should be the least of your worries.

Vectors are the most suited for access speed. Access to a random element in a vector is of complexity O(1) compared with O(n) for general linked-lists and O(log n) for link-trees.
However this question is mis-placed as the answer to your other question has lead you astray by not explaining how to fix your original problem by using a reference.

If it is the case, that you load up a vector, then process it without adding or deleting any more elements, then consider getting a pointer to the underlying array, and using array operations on that to 'avoid the vector overhead'.
If you are adding or deleting elements as part of your processing, then this is not safe to do, as the underlying array may be moved at any point by the vector itself.

Related

What is the difference between At( ) function and subscript operator in c++ string? [duplicate]

I know that at() is slower than [] because of its boundary checking, which is also discussed in similar questions like C++ Vector at/[] operator speed or ::std::vector::at() vs operator[] << surprising results!! 5 to 10 times slower/faster!. I just don't understand what the at() method is good for.
If I have a simple vector like this one: std::vector<int> v(10); and I decide to access its elements by using at() instead of [] in situation when I have a index i and I'm not sure if its in vectors bounds, it forces me to wrap it with try-catch block:
try
{
v.at(i) = 2;
}
catch (std::out_of_range& oor)
{
...
}
although I'm able to do the get the same behaviour by using size() and checking the index on my own, which seems easier and much convenient for me:
if (i < v.size())
v[i] = 2;
So my question is:
What are advantages of using vector::at over vector::operator[] ?
When should I use vector::at rather than vector::size + vector::operator[] ?
I'd say the exceptions that vector::at() throws aren't really intended to be caught by the immediately surrounding code. They are mainly useful for catching bugs in your code. If you need to bounds-check at runtime because e.g. the index comes from user input, you're indeed best off with an if statement. So in summary, design your code with the intention that vector::at() will never throw an exception, so that if it does, and your program aborts, it's a sign of a bug. (just like an assert())
it forces me to wrap it with try-catch block
No it doesn't (the try/catch block can be upstream). It is useful when you want an exception to be thrown rather than your program to enter undefined behavior realm.
I agree that most out of bounds accesses to vectors are a programmer's mistake (in which case you ought to use assert to locate those mistakes more easily; most debug versions of standard libraries do this automatically for you). You do not want to use exceptions that can be swallowed upstream to report programmer mistakes: you want to be able to fix the bug.
Since it is unlikely that an out of bounds access to a vector is part of the normal program flow (in the case it is, you're right: check beforehand with size instead of letting the exception bubble up), I agree with your diagnostic: at is essentially useless.
at can be clearer if you have a pointer to the vector:
return pVector->at(n);
return (*pVector)[n];
return pVector->operator[](n);
Performance aside, the first of these is the simpler and clearer code.
What are advantages of using vector::at over vector::operator[] ?
When should I use vector::at rather than vector::size + vector::operator[] ?
The important point here is that exceptions allow separation of the normal flow of code from the error handling logic, and a single catch block can handle problems generated from any of myriad throw sites, even if scattered deep within function calls. So, it's not that at() is necessarily easier for a single use, but that sometimes it becomes easier - and less obfuscating of normal-case logic - when you have a lot of indexing to validate.
It's also noteworthy that in some types of code, an index is being incremented in complex ways, and continually used to look up an array. In such cases, it's much easier to ensure correct checks using at().
As a real-world example, I have code that tokenises C++ into lexical elements, then other code that moves an index over the vector of tokens. Depending on what's encountered, I may wish to increment and check the next element, as in:
if (token.at(i) == Token::Keyword_Enum)
{
ASSERT_EQ(tokens.at(++i), Token::Idn);
if (tokens.at(++i) == Left_Brace)
...
or whatever
In this kind of situation, it's very hard to check whether you've inappropriately reached the end of the input because that's very dependent on the exact tokens encountered. Explicit checking at each point of use is painful, and there's much more room for programmer error as pre/post increments, offsets at the point of use, flawed reasoning about the continued validity of some earlier test etc. kick in.
In debug builds, it is not guaranteed for at() to be slower than operator[]; I'd expect them to be about the same speed. The difference is that at() specifies exactly what will happen in there is a bounds error (an exception),
where as in the case of operator[], it is undefined behavior — a crash in all of the systems I use (g++ and VC++), at least when the normal debugging flags are used. (Another difference is that once I'm sure of my code, I can get a substantial speed increase for operator[] by turning the debugging off. If the performance requires it — I wouldn't do it unless it were necessary.)
In practice, at() is rarely appropriate. If the context is such that you know the index may be invalid, you probably want the explicit test (e.g. to return a default value or something), and if you know that it can't be invalid, you want to abort (and if you don't know whether it can be invalid or not, I'd suggest that you specify your function's interface more precisely). There are a few exceptions, however, where the invalid index may result from parsing user data, and the error should cause an abort of the entire request (but not bring the server down); in such cases, an exception is appropriate, and at() will do
that for you.
The whole point of using exceptions is that your error handling code can be further away.
In this specific case, user input is indeed a good example. Imagine you want to semantically analyze an XML data-structure which uses indices to refer to some kind of resource you internally store in a std::vector. Now the XML tree is a tree, so your probably want to use recursion to analyze it. Deep down, in the recursion, there might be an access violation by the writer of the XML file. In that case, you usually want to bump out of all the levels of recursion and just reject the whole file (or any kind of "coarser" structure). This is where at comes in handy. You can just write the analysis code as-if the file was valid. The library code will take care of the error detection and you can just catch the error on the coarse level.
Also, other containers, like std::map, also have std::map::at which has slightly different semantics than std::map::operator[]: at can be used on a const map, while operator[] cannot. Now if you wanted to write container agnostic code, like something that could deal with either const std::vector<T>& or const std::map<std::size_t, T>&, ContainerType::at would be your weapon of choice.
However, all these cases usually appear when handling some kind of unvalidated data-input. If you are sure about your valid range, as you usually should be, you can usually use operator[], but better yet, iterators with begin() and end().
According to this article, performance aside, it doesn't make any difference to use at or operator[], only if the access is guaranteed to be within the size of the vector. Otherwise, if access is just based on the capacity of the vector it is safer to use at.
Note: It appears some new folks are downvoting this answer without having courtesy of telling what is wrong. Below answer is correct and can be verified here.
There is really only one difference: at does bounds checking while operator[] doesn’t. This applies to debug builds as well as release builds and this is very well specified by the standards. It’s that simple.
This makes at a slower method but it’s also really bad advice to not to use at. You have to look at absolute numbers, not relative numbers. I can safely bet that most of your code is doing fat more expensive operations than at. Personally, I try to use at because I don’t want a nasty bug to create undefined behavior and sneak in to production.

Vector move constructor slower than copy constructor

I'm working on my first C++ project, which is a CSV parser (full source code here). It's at the point where it's working, and now I want to do basic refactoring / improve performance.
Currently the way the parser works is by returning each row as a std::vector<std::string>, and I figured that instead of allocating a new vector and a new string every time I'd just have an internal vector and internal string with reserved memory that I'd clear again and again.
That worked, and I started looking at other places where I might be doing memory allocation, and I saw this function which copies the internal vector, and then clears it:
auto add_row() -> std::vector<std::string> {
auto row(m_bufvec);
m_bufvec.clear();
return row;
}
I figured that if I instead changed this line
auto row(m_bufvec);
to
auto row(std::move(m_bufvec));
It'd result in some sort of speed boost because according to http://en.cppreference.com/w/cpp/container/vector/vector it would take constant time instead of linear. To my surprise, it made the parser significantly slower (according to my really rough benchmark of running time ./main.o over this file).
I'm completely new to optimization, benchmarking, and everything else that comes with tuning C++ code. Perhaps this optimization is useless even if it worked, but regardless, I'm curious as to why std::move causes a slowdown. Am I missing something?
When you copy bufvec, its capacity is unchanged, but when you move it, its capacity is cleared. Thus, later when you fill bufvec, a logarithmic number of allocations (and log-linear element copies/moves) that are done to expand its capacity again, and such allocations can easily be your performance bottleneck.
The move version makes that function faster. But it makes other code slower. Micro optimizations do not reliably make programs faster.
Edit by OP:
The solution proposed by Cheers and hth. - Alf in the comments of m_bufvec.reserve(row.size()) after the move fixes the problem, and confirms that the above reasoning was correct. Moreover it is more efficient, (albeit only slightly) because
you avoid copying the items [in bufvec]. If the items are simple integer values, that doesn't matter so much. If the items are e.g. strings, with dynamic allocation, then it really does matter.
Indeed the first version is expected to be faster. The reason is:
auto row(m_bufvec);
invokes the copy constuctor, which allocates the necessary memory for row just at once. bufvec also keeps its allocated memory. As a result, allocations per-element are minimized, and this is important because they involve an amount of relocations.
In the second version, auto row(std::move(m_bufvec)); bufvec's memory becomes owned by row, this operation is faster than the copy constructor. But as bufvec has lost its allocated memory, when you later fill it element by element, it will do many re-allocations and (expensive) relocation. The number of re-allocations is usually logarithmic with the final size of the vector.
EDIT
The above explains the "unexpected" results in the main question. Finally, it turns out that the "ideal" for this operation is to move then reserve immediately:
auto row(std::move(m_bufvec);
m_bufvec.reserve(row.size());
return row;
This achieves the three goals:
no element-by-element allocation
no useless initialization for bufvec
no useless copying of elements from m_bufvec into row.

performance of std::vector c++ size() inside loop in member function

Similar question, but less specific:
Performance issue for vector::size() in a loop
Suppose we're in a member function like:
void Object::DoStuff() {
for( int k = 0; k < (int)this->m_Array.size(); k++ )
{
this->SomeNotConstFunction();
this->ConstFunction();
double x = SomeExternalFunction(i);
}
}
1) I'm willing to believe that if only the "SomeExternalFunction" is called that the compiler will optimize and not redundantly call size() on m_Array ... is this the case?
2) Wouldn't you almost certainly get a boost in speed from doing
int N = m_Array.size()
for( int k = 0; k < N; k++ ) { ... }
if you're calling some member function that is not const ?
Edit Not sure where these down-votes and snide comments about micro-optimization are coming from, perhaps I can clarify:
Firstly, it's not to optimize per-se but just understand what the compiler will and will not fix. Usually I use the size() function but I ask now because here the array might have millions of data points.
Secondly, the situation is that "SomeNotConstFunction" might have a very rare chance of changing the size of the array, or its ability to do so might depend on some other variable being toggled. So, I'm asking at what point will the compiler fail, and what exactly is the time cost incurred by size() when the array really might change, despite human-known reasons that it won't?
Third, the operations in-loop are pretty trivial, there are just millions of them but they are embarrassingly parallel. I would hope that by externally placing the value would let the compiler vectorize some of the work.
Do not get into the habit of doing things like that.
The cases where the optimization you make in (2) is:
safe to do
has a noticeable difference
something your compiler cannot figure out on its own
are few and far in-between.
If it were just the latter two points, I would just advise that you're worrying about something unimportant. However, that first point is the real killer: you do not want to get in the habit of giving yourself extra chances to make mistakes. It's far, far easier to accelerate slow, correct code than it is to debug fast, buggy code.
Now, that said, I'll try answering your question. The definitions of the functions SomeNotConstFunction and SomeConstFunction are (presumably) in the same translation unit. So if these functions really do not modify the vector, the compiler can figure it out, and it will only "call" size once.
However, the compiler does not have access to the definition of SomeExternalFunction, and so must assume that every call to that function has the potential of modifying your vector. The presence of that function in your loop guarantees that `size is "called" every time.
I put "called" in quotes, however, because it is such a trivial function that it almost certainly gets inlined. Also, the function is ridiculously cheap -- two memory lookups (both nearly guaranteed to be cache hits), and either a subtraction and a right shift, or maybe even a specialized single instruction that does both.
Even if SomeExternalFunction does absolutely nothing, it's quite possible that "calling" size every time would still only be a small-to-negligible fraction of the running time of your loop.
Edit: In response to the edit....
what exactly is the time cost incurred by size() when the array really might change
The difference in the times you see when you time the two different versions of code. If you're doing very low level optimizations like that, you can't get answers through "pure reason" -- you must empirically test the results.
And if you really are doing such low level optimizations (and you can guarantee that the vector won't resize), you should probably be more worried about the fact the compiler doesn't know the base pointer of the array is constant, rather than it not knowing the size is constant.
If SomeExternalFunction really is external to the compilation unit, then you have pretty much no chance of the compiler vectorizing the loop, no matter what you do. (I suppose it might be possible at link time, though....) And it's also unlikely to be "trivial" because it requires function call overhead -- at least if "trivial" means the same thing to you as to me. (again, I don't know how good link time optimizations are....)
If you really can guarantee that some operations will not resize the vector, you might consider refining your class's API (or at least it's protected or private parts) to include functions that self-evidently won't resize the vector.
The size method will typically be inlined by the compiler, so there will be a minimal performance hit, though there will usually be some.
On the other hand, this is typically only true for vectors. If you are using a std::list, for instance, the size method can be quite expensive.
If you are concerned with performance, you should get in the habit of using iterators and/or algorithms like std::for_each, rather than a size-based for loop.
The micro optimization remarks are probably because the two most common implementations of vector::size() are
return _Size;
and
return _End - _Begin;
Hoisting them out of the loop will probably not noticably improve the performance.
And if it is obvious to everyone that it can be done, the compiler is also likely to notice. With modern compilers, and if SomeExternalFunction is statically linked, the compiler is usually able to see if the call might affect the vector's size.
Trust your compiler!
In MSVC 2015, it does a return (this->_Mylast() - this->_Myfirst()). I can't tell you offhand just how the optimizer might deal with this; but unless your array is const, the optimizer must allow for the possibility that you may modify its number of elements; making it hard to optimize out. In Qt, it equates to an inline function that that does a return d->size; ; that is, for a QVector.
I've taken to doing it in one particular project I'm working on, but it is for performance-oriented code. Unless you are interested in deeply optimizing something, I wouldn't bother. It probably is pretty fast any of these ways. In Qt, it is at most one pointer dereferencing, and is more typing. It looks like it could make a difference in MSVC.
I think nobody has offered a definitive answer so far; but if you really want to test it, have the compiler emit assembly source code, and inspect it both ways. I wouldn't be surprised to find that there's no difference when highly optimized. Let's not forget, though, that unoptimized performance during debug is also a factor that might be taken into consideration, when a lot of e.g. number crunching is involved.
I think the OP's original ? really could use to give how the array is declared.

Performance of vector::size() : is it as fast as reading a variable?

I have do an extensive calculation on a big vector of integers. The vector size is not changed during the calculation. The size of the vector is frequently accessed by the code. What is faster in general: using the vector::size() function or using helper constant vectorSize storing the size of the vector?
I know that compilers usually able to inline the size() function when setting the proper compiler flags, however, making a function inline is something that a compiler may do but can not be forced.
Interesting question.
So, what's going to happened ? Well if you debug with gdb you'll see something like 3 member variables (names are not accurate):
_M_begin: pointer to the first element of the dynamic array
_M_end: pointer one past the last element of the dynamic array
_M_capacity: pointer one past the last element that could be stored in the dynamic array
The implementation of vector<T,Alloc>::size() is thus usually reduced to:
return _M_end - _M_begin; // Note: _Mylast - _Myfirst in VC 2008
Now, there are 2 things to consider when regarding the actual optimizations possible:
will this function be inlined ? Probably: I am no compiler writer, but it's a good bet since the overhead of a function call would dwarf the actual time here and since it's templated we have all the code available in the translation unit
will the result be cached (ie sort of having an unnamed local variable): it could well be, but you won't know unless you disassemble the generated code
In other words:
If you store the size yourself, there is a good chance it will be as fast as the compiler could get it.
If you do not, it will depend on whether the compiler can establish that nothing else is modifying the vector; if not, it cannot cache the variable, and will need to perform memory reads (L1) every time.
It's a micro-optimization. In general, it will be unnoticeable, either because the performance does not matter or because the compiler will perform it regardless. In a critical loop where the compiler does not apply the optimization, it can be a significant improvement.
As I understand the 1998 C++ specification, vector<T>::size() takes constant time, not linear time. So, this question likely boils down to whether it's faster to read a local variable than calling a function that does very little work.
I'd therefore claim that storing your vector's size() in a local variable will speed up your program by a small amount, since you'll only call that function (and therefore the small constant amount of time it takes to execute) once instead of many times.
Performance of vector::size() : is it
as fast as reading a variable?
Probably not.
Does it matter
Probably not.
Unless the work you're doing per iteration is tiny (like one or two integer operations) the overhead will be insignificant.
In every implementation I've, seen vector::size() performs a subtraction of end() and begin(), ie its not as fast as reading a variable.
When implementing a vector, the implementer has to make a choice between which shall be fastest, end() or size(), ie storing the number of initialized elements or the pointer/iterator to the element after the last initialized element.
In other words; iterate by using iterators.
If you are worried of the size() performance, write your index based for loop like this;
for (size_t i = 0, i_end = container.size(); i < i_end; ++i){
// do something performance critical
}
I always save vector.size() in a local variable (if the the size doesn't change inside the loop!).
Calling it on each iteration vs. saving it in a local variable can be faster.
At least, that's what I experienced.
I can't give you any real numbers, as I tested this a very long time ago. However from what I can recall, it made a noticeable difference (however potentially only in debug mode), especially when nesting loops.
And to all the people complaining about micro-optimization:
It's a single additional line of code that introduces no downsides.
You could write yourself a functor for your loop body and call it via std::for_each. It does the iteration for you, and then your question becomes moot. However, you're introducing a function call (that may or may not get inlined) for every loop iteration, so you'd best profile it if you're not getting the performance you expect.
Always get a profile of your application before looking at this sort of micro optimization. Remember that even if it performs a subtraction, the compiler could still easily optimize it in many ways that would negate any performance loss.

Is using size() for the 2nd expression in a for construct always bad?

In the following example should I expect that values.size() will be called every time around the loop? In which case it might make sense to introduce a temporary vectorSize variable. Or should a modern compiler be able to optimize the calls away by recognising that the vector size cannot change.
double sumVector(const std::vector<double>& values) {
double sum = 0.0;
for (size_t ii = 0; ii < values.size(); ++ii) {
sum += values.at(ii);
}
}
Note that I don't care if there are more efficient methods to sum the contents of a vector, this question is just about the use of size() in a for construct.
Here's one way to do it that makes it explicit - size() is called only once.
for (size_t ii = 0, count = values.size(); ii < count; ++ii)
Edit: I've been asked to actually answer the question, so here's my best shot.
A compiler generally won't optimize a function call, because it doesn't know if it will get a different return value from one call to the next. It also won't optimize if there are operations inside the loop that it can't predict the side effects of. Inline functions might make a difference, but nothing is guaranteed. Local variables are easier for the compiler to optimize.
Some will call this premature optimization, and I agree that there are few cases where you will ever notice a speed difference. But if it doesn't make the code any harder to understand, why not just consider it a best practice and go with it? It certainly can't hurt.
P.S. I wrote this before I read Benoit's answer carefully, I believe we're in complete agreement.
It all depends on what the vector's size implementation is, how aggressive the compiler is and if it listen/uses to inline directives.
I would be more defensive and introduce the temporary as you don't have any guarantees about how efficient your compiler will be.
Of course, if this routine is called once or twice and the vector is small, it really doesn't matter.
If it will be called thousands of times, then I would use the temporary.
Some might call this premature optimization, but I would tend to disagree with that assessment.
While you are trying to optimize the code, you are not investing time or obfuscating the code in the name of performance.
I have a hard time considering what is a refactoring to be an optimization. But in the end, this is along the lines of "you say tomato, I say tomato"...
Start with size() in the 'for' construct until you need to optimize for speed.
If it is too slow, look for ways to make it faster, such as using a temporary variable to hold the result of size.
No matter the optimisation settings, putting the .size() call in the second expression will be at most as performant as outlining the .size() call before the for-loop. That is:
size_t size = values.size();
for (size_t ii = 0; ii < size; ++ii) {
sum += values.at(ii)
}
will always perform at least as well as, if not better than:
for (size_t ii = 0; ii < values.size(); ++ii) {
sum += values.at(ii);
}
In practice, it probably wont matter, since outlining the .size() call is a common compiler optimisation. However, I do find the second version easier to read.
I find this even easier, though:
double sum = std::accumulate(values.begin(), values.end(), 0);
Worth noting that even if you are dealing with millions of items the overhead is going to be negligible.
In any case this should really be written using iterator - as there may be more overhead accessing a specific example.
There is really no way that the compiler can assume that size() won't change - because it could do..
If the order of iteration isn't important then you could always write it as which is slightly more efficient.
for (int i=v.size()-1; i>=0 ;i--)
{
...
}
This isn't part of the question but why are you using at in your code in place of the subscript operator []?
The sense in at is to ensure that no operation on an invalid index occurs. However, this will never be the case in your loop since you know from your code what the indices are going to be (always assuming single-threadedness).
Even if your code contained a logical error, causing you to access an invalid element, at in this place would be useless because you don't expect the resulting exception and hence you don't treat it (or do you enclose all of your loops by try blocks?).
The use of at here is misleading because it tells the reader that you (as a programmer) don't know what values the index will have – which is obviously wrong.
I agree with Curro, this is a typical case for the use of iterators. Although this is more verbose (at least if you don't use constructs like Boost.Foreach), it is also much more expressive and safer.
Boost.Foreach would allow you to write the code as follows:
double sum = 0.0;
foreach (double d, values)
sum += d;
This operation is safe, efficient, short and readable.
It doesn't matter at all. The performance overhead of .at() is so large (it contains a conditional throw statement) that a non-optimized version will spend most of its time there. An optimizing compiler smart enough to eliminiate the conditional throw will necessarily spot that size() does not change.
I agree with Benoit. The introduction of a new variable, especially an int or even a short will have a bigger benefit that calling it each time.
It's one less thing to worry about if the loop ever gets large enough that it may impact performance.
If you hold the size of the vector in a temporary variable, you will be independent of the compiler.
My guess is, that most compilers will optimize the code in a way, that size() will be called only once. But using a temporary variable will give you a guarantee, size() will only be called once!
The size method from std::vector should be inlined by the compiler, meaning that every call to size() is replaced by its actual body (see the question Why should I ever use inline code for more information about inlining). Since in most implementations size() basically computes the difference between end() and begin() (which should be inlined too), you don't have to worry too much about loss of performance.
Moreover, if I remember correctly, some compilers are "smart" enough to detect the constness of an expression in the second part of the for construct, and generate code that evaluates the expression only once.
The compiler will not know if the value of .size() changes between calls, so it won't do any optimizations. I know you just asked about the use of .size(), but you should be using iterators anyway.
std::vector<double>::const_iterator iter = values.begin();
for(; iter != values.end(); ++iter)
{
// use the iterator here to access the value.
}
In this case, the call to .end() is similar to the problem you expose with .size(). If you know the loop does not perform any operation in the vector that invalidates the iterators, you can initialize an iterator to the .end() position prior to enter the loop and use that as your boundary.
Always write code the first time exactly as you mean it. If you are iterating over the vector from zero to size(), write it like that. Do not optimise the call to size() into a temporary variable unless you have profiled the call to be a bottleneck in your program that needs optimising.
In all likelihood, a good compiler will be able to optimise away the call to size(), particularly given that the vector is declared as const.
If you were using a container where size() was O(n) (like std::list) and not O(1) (like std::vector), you would not be iterating through that container using indices. You would be using iterators instead.
Anyway, if the body of the loop is so trivial that recalculating std::vector::size() matters, then there is probably a more efficient (but possibly platform-specific) way to do the calculation, regardless of what it is. If the body of the loop is non-trivial, recalculating std::vector::size() each time is unlikely to matter.
If you are modifying the vector (adding or removing elements) in the for loop then you should not use a temporary variable since this could lead to bugs.
If you are not modifying the vector size in the for loop then I would all the time use a temporary variable to store the size (this would make your code independant on the implementation details of vector::size.
In such cases using iterators is cleaner - in some it's even faster. There's only one call to the container - getting the iterator holding a pointer to the vector member if there are any left, or null otherwise.
Then of course for can become a while and there are no temporary variables needed at all - you can even pass an iterator to the sumVector function instead of a const reference/value.
Most, maybe even all, standard implementations of size() will be inlined by the compiler to what would be the equivalent of a temporary or at most a pointer dereference.
However, you can never be sure. Inlining is about as hidden as these things get, and 3rd party containers may have virtual function tables - which means you may not get inlined.
However, seriously, using a temporary reduces readability slightly for almost certainly no gain. Only optimise to a temporary if profiling says it is fruitful. If you make these micro optimisations everywhere, your code could become unreadable, perhaps even for yourself.
As a slight aside, no compiler would optimise size() to one of call assigning to a temporary. There is almost no guarantee of const in C++. The compiler cannot risk assuming size() will return the same value for the whole loop. For example. Another thread could change the vector in between loop iterations.