views:

393

answers:

3

The topic generically says it all. Basically in a situation like this:

boost::scoped_array<int> p(new int[10]);

Is there any appreciable difference in performance between doing: &p[0] and p.get()?

I ask because I prefer the first one, it has a more natural pointer like syntax. In fact, it makes it so you could replace p with a native pointer or array and not have to change anything else.

I am guessing since get is a one liner "return ptr;" that the compiler will inline that, and I hope that it is smart enough to to inline operator[] in such a way that it is able to not dereference and then immediately reference.

Anyone know?

+2  A: 

The only way to know is to actually measure it!

But if you have the source of the boost:scoped_array you could llok at the code and see what it does. I am sure it is pretty similar.

T * scoped_array::get() const // never throws
{
    return ptr;
}

T & scoped_array::operator[](std::ptrdiff_t i) const // never throws
{
    BOOST_ASSERT(ptr != 0);
    BOOST_ASSERT(i >= 0);
    return ptr[i];
}

Write two versions of the code (one using get() the other using operator[]). Compile to assembley with optimizations turned on. See if your compiler actually manages to optimize away the ptr+0.

Martin York
Evan Teran
You are asking if the compiler is smart enough to optimise away 'ptr + 0'. Check the output of your compiler.
Martin York
heh, you could just say "i don't know" :-P. Anyway, I know if p was a native pointer it could. I suppose if the param of operator[] is known at compile time it *should* be able to factor it all. I wonder if it does.
Evan Teran
I would rather say it is impossable to know the answer without more exact information. Since this is easy for you to do all by yourself, maybe its somthing you should try by hand ;-)
Martin York
+1  A: 

OK, I've done some basic tests as per Martin York's suggestions.

It seems that g++ (4.3.2) is actually pretty good about this. At both -O2 and -O3 optimization levels, it outputs slightly different but functionally equivalent assembly for both &p[0] and p.get().

At -Os as expected, it took the path of least complexity and emits a call to the operator[]. One thing to note is that the &p[0] version does cause g++ to emit a copy of the operator[] body, but it is never used, so there is a slight code bloat if you never use operator[] otherwise:

The tested code was this (with the #if both 0 and 1):

#include <boost/scoped_array.hpp>
#include <cstdio>

int main() {
    boost::scoped_array<int> p(new int[10]);
#if 1
    printf("%p\n", &p[0]);
#else
    printf("%p\n", p.get());
#endif
}
Evan Teran
Konrad Rudolph
Wow, good call, the asm is *identical* with -DNDEBUG, if you provide an answer containing that, I'll accept it.
Evan Teran
A: 

Is this a question you're asking just for academic interest or is this for some current code you're writing?

In general, people recommend that code clarity is more important that speed, so unless your sure this is going to make a difference you should pick whichever option is clearer and matches your code base. FWIW, I personally think that the get() is clearer.

David Norman
Evan Teran