views:

540

answers:

3

Is there a full list of optimizations done by the /optimize C# compiler key available anywhere?

EDIT: Why is it disabled by default? Is it worth using in a real-world app? -- it is disabled by default only in Debug configuration and Enabled in Release.

+2  A: 

It is disabled by default for debug builds. For Release builds it is enabled.

It is definitely worth enabling this switch as the compiler makes lots of tweaks and optimizations depending on the kind of code you have. For eg: Skipping redundant initializations, comparisons that never change etc.

Note: You might have some difficulty debugging if your turn on optimization as the code you have and the IL code that is generated may not match. This is the reason it is turned on only for Release builds.

Bobby Alexander
Oh, indeed. I'll update the question. But I still wonder what is the exact (or full enough) list of optimizations...
Yacoder
+2  A: 

Quoted from the MSDN page:

The /optimize option enables or disables optimizations performed by the compiler to make your output file smaller, faster, and more efficient.

In other words, it does exactly what you think it would - optimises the compiled CIL (Common Intermediate Language) code that gets executed by the .NET VM. I wouldn't worry about what the specific optimisations are - suffice to say that they are many, and probably quite complex in some cases. If you are really interested in what sort of things it does, you could probably investigate the Mono C# Compiler (I doubt the details about the MS C# one are public).

The reason optimisation is disabled by default for Debug configurations is that it makes certain debugging features impossible. A few notable ones:

  • Perhaps most crucially, the Edit and Continue feature is disabled - i.e. no modifying code during execution.
  • Breaking execution often means the wrong line of code is highlighted (usually the one after the expected one).
  • Unused local variables aren't actually assigned or even declared.

Really, the default options for optimisation never ought to be changed. Having the option off for debugging is highly useful, while having it on for Release mode is equally wise.

Noldorin
I don't worry about the optimizations, I'd just like to know what they are :-)I'd like to upvote your effort as well, but one thing stops me from doing that: ".NET VM" :-)
Yacoder
+ 1 vote. Even though the term is far from precise, calling the CLR a VM is not, from a conceptual standpoint, totally wrong. You have pseudo machine code, CIL, that runs on a machine that does not exist, but is emulated by the CLR. It can be argued that the fact that the CLR JITs the code is an implementation detail, even though one that carries huge (mostly beneficial) consequences.
Rui Craveiro
@Rui: Thanks... And yeah, I understood that it's technically the CLR, but I tend to use the terms interchangeably for the sake of many arguments. Your explanation does clarify things, however. It's also worth noting that the Java equivalent of the CLR is explicitly called a VM (the JVM), and I believe even MS refer to it as a VM at times, so the term is fairly commonly used in this context.
Noldorin
Java had its virtual machine implemented as a byte-code interpreter for quite some time. .NET never had that structure, so MSIL was never "executed" per se, only compiled.
Yacoder
@Yacoder: compiled at runtime is different from AOT compiling. The IL bytecode is the intermediate language, thus the CLR is a classic VM that abstracts away the underlying hardware.I wished people wouldn't get so caught up in semantics, specially when they are wrong.
Alexandru Nedelcu
@Alexandru: Yes, exactly. I don't much care for this pedantry either...
Noldorin
Well, in a sense _any language_ creates a layer of abstraction over the hardware and thus creates a virtual machine. That's why I neither downvote the answer. It's not wrong. It's just not really the best way of describing how the CLR works, especially in comparison with the classic Java VM, which was interpreting the byte-code and had no JIT compilator.
Yacoder
+4  A: 

Scott Hanselman has a blog post that shows a few examples of what /optimize (which is enabled in Release Builds) does.

As a summary: /optimize does many things with no exact number or definition given, but one of the more visible are method inlining (If you have a Method A() which calls B() which calls C() which calls D(), the compiler may "skip" B and C and go from A to D directly), which may cause a "weird" callstack in the Release build.

Michael Stum
Nice, thanks :-)
Yacoder