Hack 63. Examine the IL Generated by Your CodeUse ILDASM to unearth insight into what your code is doing under the hood. Microsoft's .NET platform is in large part built upon the common intermediate language ( CIL, MSIL, or IL for short).
All of the various languages that you can use with .NET, Visual Basic.NET, C#, J#, Cobol.NET, and so forth are compiled into IL. When you compile a C# Project, your code is not compiled into machine code (as a nonmanaged C++ application would be), but instead is compiled into IL. When your application is run, the IL of your application is then compiled by the JIT (just-in-time) compiler and turned into machine code. This machine code can then be executed and your application can be run.
Most of the time, you don't have to even think about the IL that your code is compiled into, but sometimes being able to examine this IL can be very useful. Among the many reasons to look at the IL generated by your code, you may want to: Better understand what your code is doing Compare the performance of different coding approaches Compare the differences between various .NET languages Diagnose difficult bugs
In this hack, you will learn how to examine IL to compare two different ways of performing the same action. The .NET Framework includes a large number of different ways to do the same things. You can add strings together using the normal addition sign or the StringBuilder object, you can set a string to empty using empty double quotes (") or the string.Empty property, and so on. IL presents an interesting way to view how each of these is treated when compiled into IL. 7.6.1. Microsoft Intermediate Language Disassembler (ILDASM)
MSIL Disassembler (ILDASM) is an application that is included with the Microsoft .NET Framework SDK. You don't even need Visual Studio to use ILDASM. (But if you don't have Visual Studio, I really don't know why you bought this book.) Using ILDASM you can examine the IL contained in your assemblies or executables. The easiest way to launch ILDASM is to open the Visual Studio command prompt and type in ildasm. You can also find the file in the following locations:
%ProgramFiles%\Microsoft Visual Studio .NET\FrameworkSDK\Bin
%ProgramFiles%\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin
If you have only the framework SDK installed, it will be in the <SDK Directory>\Bin directory. You can see the ILDASM application in Figure 7-20. Figure 7-20. ILDASM main windowThis is a pretty plain window and doesn't hint at the true potential of this application. First, I am going to set up a small example of two different ways to create an empty string, and then using ILDASM, I'll determine which method is more efficient. Here is the first method using simple empty quotations: public class ILDASMTest { public string GetBlankString1( ) { string s = "; return s; } The second method uses the string.Empty field: public string GetBlankString2( ) { string s = string.Empty; return s; } } Now I will need to compile both of these methods into an assembly and
load that assembly into ILDASM. You can compile it at the command
line with csc /t:library /out:ILDASMTest.dll
ProgramName.cs or create a project and compile it. To open
the assembly in ILDASM, click on File Figure 7-21. ILDASM assembly viewFrom this screen, you can see the two methods in the assembly. Double-clicking on each of these methods will show the IL that makes up this method. Here is the IL for the first string method: .method public hidebysig instance string GetBlankString1( ) cil managed { // Code size 12 (0xc) .maxstack 1 .locals init ([0] string s, [1] string CS$00000003$00000000) IL_0000: ldstr " IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: br.s IL_000a IL_000a: ldloc.1 IL_000b: ret } // end of method Class1::GetBlankString1 And here is the IL from the second string method: .method public hidebysig instance string GetBlankString2( ) cil managed { // Code size 12 (0xc) .maxstack 1 .locals init ([0] string s, [1] string CS$00000003$00000000) IL_0000: ldsfld string [mscorlib]System.String::Empty IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: stloc.1 IL_0008: br.s IL_000a IL_000a: ldloc.1 IL_000b: ret } // end of method Class1::GetBlankString2 At first glance, IL is a little confusing, and I don't plan on trying to teach you everything about IL in this hack. But looking at these two simple examples, you will see one major difference. In the first method, you will see that the IL_0000: line contains this line of code: IL_0000: ldstr " And on the same line in the second method is this line of code: IL_0000: ldsfld string [mscorlib]System.String::Empty To understand these two lines, you first need to understand what the commands ldstr and ldsfld actually do. The IL command ldstr creates a new string (or most likely pulls it from the string pool). The IL command ldsfld loads a static field from a class. Using the first string method creates a new string object, whereas the second method simply loads the value of a static field. To be sure, this is a tiny difference in these two procedures. You would probably never notice the performance difference between these two methods, even if you ran the process hundreds of times. But understanding the difference and how the .NET Framework works is what's important. The second method of creating an empty string (using string.Empty) is technically more efficient than the first method. (Of course, after I learned this. I have always used string.Empty because there is no reason not to.) This is a simplistic example of using ILDASM, but it does an excellent job of demonstrating how ILDASM can be used to better understand the .NET Framework. 7.6.2. Advanced ILDASM
ILDASM also includes an advanced mode. This advanced mode can be activated by calling the ildasm.exe executable using the /ADV switch. This enables a number of different extra views that are not available when running ILDASM in normal mode. One of the more interesting views is the statistics view that is shown in Figure 7-22. Figure 7-22. ILDASM StatisticsThis view reports on all kinds of interesting information including the size of the file and what percentages different parts of the file contribute to the whole. For more information on the advanced mode of ILDASM, please refer to the ILDasmAdvancedOptions.doc file that is in the same directory as the ILDASM executable.
|