views:

317

answers:

4

Does the compiler optimize out any multiplications by 1? That is, consider:

int a = 1;
int b = 5 * a;

Will the expression 5 * a be optimized into just 5? If not, will it if a is defined as:

const int a = 1;
+11  A: 

It will pre-calculate any constant expressions when it compiles, including string concatenation. Without the const it will be left alone.

Your first example compiles to this IL:

.maxstack 2
.locals init ([0] int32, [1] int32)

ldc.i4.1   //load 1
stloc.0    //store in 1st local variable
ldc.i4.5   //load 5
ldloc.0    //load 1st variable
mul        // 1 * 5
stloc.1    // store in 2nd local variable

The second example compiles to this:

.maxstack 1
.locals init ( [0] int32 )

ldc.i4.5 //load 5 
stloc.0  //store in local variable
Mark Cidade
Even without the const, a competent compiler will know that 'a' doesn't change between being assigned and being used.
A competent compiler can assume that but it can't know if, for whatever reason, pushing an int onto the stack will prevent it from loading it into a local variable.
Mark Cidade
Was that with or without optimisation?
1800 INFORMATION
I used these switched with the 3.0 compiler: /utf8output /debug- /optimize+ /w:4
Mark Cidade
That's totally weird, and kind of lame - any decent compiler of the last 20 or 30 years would have optimised that away
1800 INFORMATION
The JIT compiler is a lot smarter. It will inline methods, etc.
Mark Cidade
So in order to accurately answer the question, you'd have to look at the output after the JIT compiler has had a go?
1800 INFORMATION
I'd like to see the JITted output but I have no idea how...
Erik Forbes
IT JITs it to the x86 instruction set which can be disassembled in a debugger.
Mark Cidade
Aah. Duh. Lol. Now that I can play with.
Erik Forbes
+1 for you, -several million for the compiler
The JIT is the place for target-specific optimisations though, no? Why do optimisations at JIT-time that you could've done at compile-time?
Mike F: It means only writing the optimisation code once. Of course, it means *running* the optimisation code every time the code runs... arguably the best solution for this kind of thing would be a language-neutral IL optimisation phase at compile-time but after the language oompiler had run.
Jon Skeet
Aaaaah...the best place for constant propagation would be at link-time, no? Is this listing pre- or post-link?
This is after static linking (of object code).
Mark Cidade
+1  A: 

Constant propagation is one of the most common and easiest optimisations.

1800 INFORMATION
+1  A: 

What the compiler would optimise here is not multiplication by 1 per-se, but rather arithmetic with values known at compile-time. So yeah, a compiler would optimise out all the maths in your example, with or without the const.

Edit: A competent compiler, I should say.

I compiled and disassembled it and it didn't optimize away the non-const expression.
Mark Cidade
Is it possible that the JIT would optimize it out at runtime, though?
Neil Williams
@Neil Williams: You'd hope so, but the JIT is really not the place to be figuring out stuff you could've figured out at compile-time.
+1  A: 

Looking at the code generated by the mono compiler, the version with the non-const a performs the multiplication at run time. That is, the multiplication is not optimized out. If you make a const, then the multiplication is optimized out.

The Microsoft compiler might have a more aggressive compiler, the best solution is to look at the code generated by the compiler to see what it is doing.

Dave Tarkowski