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.
The operator[] is 5 to 10 times faster than at(), both in release & debug builds (VS2008 x86). Reading a bit on the web got me to realize that at() has boundary checking.
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.
it is faster to search an item against a set than a vector (O(log(n)) vs O(n)).
Basically vector is a dynamic array that has the ability to resize itself automatically when an element add or removed from the vector. A vector element store in a continuous manner so we can access the element using the index.
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.
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