C ++ Vector at / [] operator speed

To give functions, you can change a vector that I cannot 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 indicated in the answer to my other question)

  • I am going to make many calls to myvec.at() . How fast is this, compared to the first example, using a variable to store the result?

  • Is there any other option for me? Can I use pointers in any way?

When it gets serious, thousands of calls will be myvec.at() per second. Therefore, every little elderly person is important.

+7
c ++ vector stl
Apr 05 '10 at 13:39
source share
9 answers

You can use the link:

 int &curr = myvec.at(i); // do stuff with curr 

The member function at restricts validation to ensure that the argument is within the size of vector . Profiling is the only way to find out how slower it compares to operator[] . Using the link here, you can search 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.

+17
Apr 05 '10 at 13:44
source share
— -

From my own tests with similar code (compiled under gcc and Linux), operator[] can be noticeably faster than at , and not because of border checks, but because of the overhead of handling exceptions. Replacing at (which throws an exception on extraordinary borders) with checking my own boundaries, which raised assert to out-bounds, gave a measurable improvement.

Using the link, as Cristo said , you can only perform an overhead check once.

Ignoring bounds checking and exception handling overhead, both operator[] and at should be optimized to equivalent direct array access or direct access with a pointer.

As Chris Becke said, there is no substitute for profiling.

+4
Apr 05 2018-10-05T00:
source share

The [] operator may be faster than at , because it does not require border checking.

You can make a curr link to do what you want.

 MyClass & curr = myvec.at(i); 

You can also benchmark before worrying. Modern processors easily cope with thousands of operations per second.

+2
Apr 05 2018-10-10T00:
source share

When performance is a problem, there is no substitute for profiling. Compiler optimization capabilities vary from version to version, and minor, minor changes in the source code can significantly change the final performance.

No one can answer this question, but you yourself: create a test harness and drop some algorithms on it and see what you get.

ps. if performance is really a problem, well, I got a speed factor of 10 from a png decoder by deleting the vectors and replacing them with raw arrays. Again, this was for Visual Studio 6. I am not saying that replacing a raw array will give you a 10-fold improvement, but this is what you should try.

+2
Apr 05 '10 at 13:44
source share

The reason the first one does not work is because you are not setting the pointer or iterator to the address of the ith variable. Instead, you set the value equal to the value of the ith variable, and then change the current value. I assume that doThis and doThat are links.

Do it:

 MyObject& curr = myvec.at( i ); 
+2
Apr 05 '10 at 13:44
source share

The options that I see are roughly in the reverse order of preference :

  • Store pointers in a container instead of real objects. In any case, this may be advisable if the objects are complex enough that copying them is problematic.
  • Use the index operator [] instead of at() .
  • Just call at() once and save it in a link (see Cristo's answer above).
  • Forget it until you have a problem with excessive execution time. If this happens, first profile your code to make sure the bottleneck is there, and only then worry about doing one of the above to speed up the process.

Honestly, you should play around with four different approaches and just use the one that provides the easiest code to understand. In most cases, we are happy to sacrifice a few machine cycles for code that is easier for people to maintain.

+1
Apr 05 '10 at 13:57 on
source share

The complexity of at() constant, i.e. in practice, this means that it must be designed so as not to have a corresponding decrease in performance.

You can use [] , which is also constant complexity, but does not check boundaries. This would be equivalent to using pointer arithmetic and therefore potentially a little faster than the first.

In any case, the vector is specifically designed for continuous access to performance for any of its elements. So this should be the least of your worries.

0
Apr 05 '10 at 13:44
source share

Vectors are most suitable for access speed. Accessing a random element in a vector has O (1) complexity compared to O (n) for common linked lists and O (log n) for spanning trees.

However, this question is incorrect, as the answer to your other question made you go astray without explaining how to fix your original problem using the link.

0
Apr 05 '10 at 13:59 on
source share

If so, you load the vector and then process it without adding or removing more elements, and then consider getting a pointer to the underlying array and using array operations to do this to “avoid the overhead of the vector.”

If you add or remove elements as part of your processing, this is not safe, since the underlying array can be moved at any point by the vector itself.

0
Apr 05 '10 at 16:35
source share



All Articles