Hack 63. Examine the IL Generated by Your Code![]() 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).
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.
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 doingCompare the performance of different coding approachesCompare the differences between various .NET languagesDiagnose 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 window![]() 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 {The second method uses the string.Empty field: public string GetBlankString2( )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 the assembly in the file dialog. After selecting the assembly, you will see the screen shown in Figure 7-21. Figure 7-21. ILDASM assembly view![]() 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 stringAnd here is the IL from the second string method: .method public hidebysig instance stringAt 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::EmptyTo 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 ILDASMILDASM 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 Statistics![]() 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. |