I am trying to optimize my application for for it to perform well right after it is started. At the moment, its distribution contains 304 binaries (including external dependencies) totaling 57 megabytes. It is a WPF application doing mostly database access, without any significant calculations.
I discovered that the Debug configuration offers way better (~5 times gain) times for most operations, as they are performed for the first time during the lifetime of the application's process. For example, opening a specific screen within the app takes 0.3 seconds for NGENed Debug, 0.5 seconds for JITted Debug, 1.5 seconds for NGENed Release and 2.5 seconds for JITted Release.
I understand that the gap in JIT compilation time is caused by the JIT compiler applying more aggressive optimizations for the Release binaries. From what I can tell, Debug and Release configurations differ by the /p:DebugType
and /p:Optimize
switches passed to the C# compiler, but I see the same performance gap even if I build the application with /p:Configuration=Release /p:DebugType=full /p:Optimize=false
– that is, the same image debug options as in /p:Configuration=Debug
.
I confirm that the options were applied by looking at the DebuggableAttribute
applied to the resulting assembly. Observing the NGEN output, I see <debug>
added to the names of some assemblies being compiled – how does NGEN distinguish between debug and non-debug assemblies? The operation being tested uses dynamic code generation – what level of optimization is applied to dynamic code?
Note: I am using the 32-bit framework due to external dependencies. Should I expect different results on x64?
Note: I also do not use conditional compilation. So the compiled source is the same for both configurations.