In terms of space-time complexity which of the following is best way to iterate over a std::vector and why?
Way 1:
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) { /* std::cout << *it; ... */ }
Way 2:
for(std::vector<int>::size_type i = 0; i != v.size(); i++) { /* std::cout << v[i]; ... */ }
Way 3:
for(size_t i = 0; i != v.size(); i++) { /* std::cout << v[i]; ... */ }
Way 4:
for(auto const& value: a) { /* std::cout << value; ... */
Use a for loop and reference pointer.
A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.
Yes, the elements of a std::vector are guaranteed to be contiguous.
Difference between std::vector and std::array in C++ As array is fixed size, once initialized can't be resized. Vector occupies more memory. Array is memory efficient data structure. Vector takes more time in accessing elements.
It really depends on what you are doing, but if you have to keep re-declaring the iterator, Iterators become MARGINALLY SLOWER. In my tests, the fastest possible iteration would be to declare a simple * to your vectors array and Iterate through that. Vector Iteration and pulling two functions per pass. But if you did it with pointers...
However, if you're only iterating over a single array, then an iterator may very well be faster, since it avoids the need to add an offset to an existing base pointer.
YMMV, but if using an index makes the code more readable/understandable, you should do it. With modern compilers, all options are practically free, but iterators are very slightly better for iterating and easier to use with range-for loops ( for (auto& x: vs) ).
Then this will probably also be slower than the iterator version, because sizeof (T) is not a power of 2, and therefore you are (again) multiplying by 37 each time you loop!
First of all, Way 2 and Way 3 are identical in practically all standard library implementations.
Apart from that, the options you posted are almost equivalent. The only notable difference is that in Way 1 and Way 2/3, you rely on the compiler to optimize the call to v.end()
and v.size()
out. If that assumption is correct, there is no performance difference between the loops.
If it's not, Way 4 is the most efficient. Recall how a range based for loop expands to
{ auto && __range = range_expression ; auto __begin = begin_expr ; auto __end = end_expr ; for ( ; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
The important part here is that this guarantees the end_expr
to be evaluated only once. Also note that for the range based for loop to be the most efficient iteration, you must not change how the dereferencing of the iterator is handled, e.g.
for (auto value: a) { /* ... */ }
this copies each element of the vector into the loop variable value
, which is likely to be slower than for (const auto& value : a)
, depending on the size of the elements in the vector.
Note that with the parallel algorithm facilities in C++17, you can also try out
#include <algorithm> #include <execution> std::for_each(std::par_unseq, a.cbegin(), a.cend(), [](const auto& e) { /* do stuff... */ });
but whether this is faster than an ordinary loop depends on may circumstantial details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With