Rather, is there a way to tell if it's been compiled with the optimization parameter enabled or disabled. I don't want to know if it's release or debug, since either can be enabled with or without optimizations. From my perspective, even though the code says it's release version, is it truly optimized? Thanks.
4 Answers
One way to check is to look at the DebuggableAttribute
(doc) on the assembly. The DisableOptimizations
flag will not be set if the C# complier was passed the /optimize option.
Note: Although this will work for the majority of scenarios this is not a 100% fool proof solution. It can be broken it at least the following ways
- Compiling with another language that has different semantics for optimization
- If the user hand defines the
DebuggableAttribute
it will take precedence over what the C# compiler defines

- 733,204
- 149
- 1,241
- 1,454
-
1. is probably not a problem, as the question was about C# assemblies, however, wouldn't 2. be still valid (if the user overrides the attribute, wouldn't that get rid of the runtime optimizations and thus the assembly could be thought of as not optimized?) – Zaki Aug 20 '10 at 18:21
-
@Zaki yes and no. JIT optimizations would be disabled but other C# compiler optimizations would not be enabled. – JaredPar Aug 20 '10 at 18:25
-
@Hans, confused myself with the negatives. Fixed. – JaredPar Aug 20 '10 at 18:50
-
Sweet, thanks folks. Found this on Scott Hanselman's blog giving code to do just that. Thanks. http://www.hanselman.com/blog/HowToProgrammaticallyDetectIfAnAssemblyIsCompiledInDebugOrReleaseMode.aspx – John Aug 20 '10 at 21:08
-
Note that you can use ILSpy (or similar tools) to see the attributes of an assembly. – yoyo Sep 15 '15 at 01:11
Look at the assembly manifest with Ildasm.exe:
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(
valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes)
= ( 01 00 02 00 00 00 00 00 )
That's the Release version. The debug build values are ( 01 00 07 01 00 00 00 00 )
Yet another wrinkle is that the debugger can disable the JIT optimizer. That's a configurable option in VS, Tools + Options, Debugging, General, "Suppress JIT optimization on module load". You want that off if you're debugging the Release build and want comparable perf. It makes debugging more challenging, stepping acts weird as the optimizer rearranges and inlines code and you often cannot inspect the values of local variables because they are stored in CPU registers.

- 922,412
- 146
- 1,693
- 2,536
-
When I set to enabled, the C# "Optimize Code", and rebuild in debug, I still see the debug values you're referencing. // --- The following custom attribute is added automatically, do not uncomment ------- // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) – John Nov 01 '12 at 17:41
-
I just re-checked with VS2012. Nope, still works like I described. Don't forget to rebuild after changing the option. – Hans Passant Nov 01 '12 at 18:01
-
1Thank you. I get what I described above when the code is not optimized, which matches your description, but when I do have it optimized, set by default in Release mode, there's no mention of the debug attribute at all in the manifest. Yes, this is in conflict with my statement above, apologies. I'll continue to look at my assemblies and see if I can see the DebuggableAttribute with the build value you mentioned - when code is set to optimize. This is VS2010. Thanks. – John Nov 01 '12 at 19:18
-
1In doing some following up to this approach, it appears that the DebuggableAttribute value of "( 01 00 02 00 00 00 00 00 )" is an optimized assembly, but with pdb-only output. If the assembly is optimized with output set to full, the DebuggableAttribute appears to be "( 01 00 03 00 00 00 00 00 )". And finally, if it's optimized, with output set to none, there will be no DebuggableAttribute at all here. – John Nov 01 '12 at 22:12
I'm 8 years late but if you, like me, wanted a C# way, here it is:
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
internal static class AssemblyExtensions
{
public static bool IsOptimized(this Assembly asm)
{
var att = asm.GetCustomAttribute<DebuggableAttribute>();
return att == null || att.IsJITOptimizerDisabled == false;
}
}
As an extension method:
static void Main(string[] args)
{
Console.WriteLine("Is optmized: " + typeof(Program).Assembly.IsOptimized());
}

- 6,029
- 3
- 25
- 38
This post might help you http://www.panopticoncentral.net/archive/2004/02/03/267.aspx
Specifically, in ildasm, you could look for the DebuggableAttribute and the absence of NOPs.

- 1,101
- 9
- 7
-
that info is specific to the VB.Net compiler. It has very similar but slightly different semantics than C#. – JaredPar Aug 20 '10 at 18:12