tags:

views:

136

answers:

3

I often use references to simplify the appearance of code:

vec3f& vertex = _vertices[index];

// Calculate the vertex position
vertex[0] = startx + col * colWidth;
vertex[1] = starty + row * rowWidth;
vertex[2] = 0.0f;

Will compilers recognize and optimize this so it is essentially the following?

_vertices[index][0] = startx + col * colWidth;
_vertices[index][1] = starty + row * rowWidth;
_vertices[index][2] = 0.0f;
+3  A: 

Compilers will even do more clever stuff than this. Maybe they'll do

vec3f * vertex = _vertices[index];

*vertex++ = startx + col * colWidth;
*vertex++ = starty + row * rowWidth;
*vertex++ = 0.0f;

Or even other variations …

Didier Trosset
Naive execution of that one would almost certainly be slower. You just created dependencies between the three assignments where none existed before.
jalf
That also looks fast to me. The dependencies may take time but there are additional calculations and memory writes that can be interleaved.
MSalters
+8  A: 

Yes. This is a basic optimization that any modern (and even ancient) compilers will make.

In fact, I don't think it's really accurate to call that you've written an optimisation, since the move straightforward way to translate that to assembly involves a store to the _vertex address, plus index, plus {0,1,2} (multiplied by the appropriate sizes for things, of course).

In general though, modern compilers are amazing. Almost any optimization you can think of will be implemented. You should always write your code in a way that emphasizes readability unless you know that one way has significant performance benefits for your code.

As a simple example, code like this:

int func() {
    int x;
    int y;
    int z;
    int a;

    x = 5*5;
    y = x;
    z = y;
    a = 100 * 100 * 100* 100;

    return z;
}

Will be optimized to this:

int func() {
    return 25
}

Additionally, the compiler will also inline the function so that no call is actually made. Instead, everywhere 'func()' appears will just be replaced with '25'.

This is just a simple example. There are many more complex optimizations a modern compiler implements.

smehmood
+1 for "You should always write your code in a way that emphasizes readability". Don't try micro-optimization like this unless you have *profiled* your code and *measured* that you got a problem *at this point*. That being said, the OP's use of a reference to get rid of one index in the following expressions could be considered a "readability optimization" in itself, so I'm content. ;-)
DevSolar
The "amazingness" is actually depends on compiler and hardware.
n0rd
+2  A: 

Depending on the types of your variables, what you've described is a pessimization.

If vertices is a class type then your original form makes a single call to operator[] and reuses the returned reference. Your second form makes three separate calls. It can't necessarily be inferred that the returned reference will refer to the same object each time.

The cost of a reference is probably not material in comparison to repeated lookups in the original vertices object.

Except in limited cases, the compiler cannot optimize out (or pessimize in) extra function calls, unless the change introduced is not detectable by a conforming program. Often this requires visibility of an inline definition.

This is known as the "as if" rule. So long as the code behaves as if the language rules have been followed exactly, the implementation may make any optimizations it sees fit.

Charles Bailey
What if `operator[]` is fairly trivial, like `return data[index];`, and is declared `inline`?
Thomas
@Thomas: Then paragraphs four and five might apply.
Charles Bailey
It's the "might" that I'm wondering about ;)
Thomas
@Thomas: I'm not quite sure what you're asking; I don't think it's possible to answer in any more detail what _might_ happen without looking at particular implementations.
Charles Bailey