Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to ensure copy elision?

Copy elision is a neat optimization technique and in some cases relying on copy elision can actually be faster than passing around references "by hand".

So, let's assume you have identified a critical code path where you rely on the fact that the copy elision is performed by your compiler for the code path for maximum performance.

But now you are relying on a compiler optimization.

Is there any (compiler specific, obviously) way to ensure that the copy elision is actually performed and have the compiler (or another tool) generate a warning/error if the copy elision cannot be performed?

(I'm thinking of something remotely similar to Visual C++'s __forceinline than will generate a warning if the function marked thus isn't inlined by the compiler.)

like image 991
Martin Ba Avatar asked May 26 '11 14:05

Martin Ba


2 Answers

Not really, except putting an assert(false); in the copy constructor.

Otherwise use your favorite profiler to measure that the interesting parts of your app is fast enough.

like image 165
Bo Persson Avatar answered Oct 19 '22 04:10

Bo Persson


No.

But you can write an equivalent, although completely unreadable, code:

BigObj f()
{
    BigObj x(g());
    x.someMethod();
    return x;
}

//...
BigObj z = f();
//...

is translated (with copy elision) to:

void f(BigObj* obj)
{
    new(obj) BigObj(g());
    obj->someMethod();
}

//...
char z[sizeof(BigObj)];
f((BigObj*)&z[0]);
//...
((BigObj*)&z[0])->~BigObj();

But seriously, just write your code in such a way that the compiler can elide the copy. I.e. return only one object without branching:

BigObj f()
{
    BigObj x, y;
    // use x and y
    if(condition)
        return x;
    else
        return y;
    // cannot be elided
}


BigObj f()
{
    if(condition)
    {
        BigObj x;
        return x;
    }
    else
    {
        BigObj y;
        return y;
    }
    // can be elided
}
like image 39
Yakov Galka Avatar answered Oct 19 '22 03:10

Yakov Galka