Recipe 3.37 Determining Where Boxing and Unboxing Occur

Problem

You have a project consisting of some very complex code that is a performance bottleneck for the entire application. You have been assigned to increase performance, but you do not know where to start looking.

Solution

A great way to start looking for performance problems is to use a profiling tool to see whether boxing is actually causing you any kind of problem in the first place. A profiler will show you exactly what allocations are occurring and in what volume. There are several profilers on the market; some are free and others are not.

If you have already established through profiling that boxing is definitely causing a problem but you are still having trouble working out where it's occurring, then you can use the Ildasm disassembler tool that is packaged with VS.NET. With Ildasm you can convert an entire project to its equivalent IL code and then dump the IL to a text file. To do this, Ildasm has several command-line switches, one of which is the /output switch. This switch is used as follows :

 ildasm Proj1.dll /output:Proj1.il 

This command will disassemble the file Proj1.dll and then write the disassembled IL to the file Proj1.il .

A second useful command-line switch is /source . This switch shows the original code (C#, VB.NET, etc.) in which this DLL was written, as well as the IL that was compiled from each of these source lines. Note that the DLL must be built with debugging enabled. This switch is used as follows:

 ildasm Proj1.dll /output:Proj1.il /source 

We prefer the second method of invoking Ildasm, since the original source is included, preventing you from getting lost in all of the IL code.

After running Ildasm from the command line, open the resulting IL code file into VS.NET or your favorite editor. Inside the editor, do a text search for the words box and unbox . This will find all occurrences of boxing and unboxing operations.

Using this information, you have pinpointed the problem areas. Now, you can turn your attention to them to see if there is any way to prevent or minimize the boxing/unboxing operations.

Discussion

When a boxing or unboxing operation occurs in code, whether it was implicit or explicit, the IL generated includes the box or unbox command. For example, the following C# code:

 int valType = 1; object boxedValType = valType; valType = (int)boxedValType; 

compiles to the following IL code:

 //000883:          int valType = 1;   IL_0000:  ldc.i4.1   IL_0001:  stloc.0 //000884:          object boxedValType = valType;   IL_0002:  ldloc.0  IL_0003:  box        [mscorlib]System.Int32  IL_0008:  stloc.1 //000898:          int valType = (int) boxedValType;   IL_0061:  ldloc.1  IL_0062:  unbox      [mscorlib]System.Int32  IL_0067:  ldind.i4 

Notice the box and unbox commands in the previous IL code. IL makes it very apparent when a boxing or unboxing operation occurs. We can use this to our advantage to find and hopefully prevent a boxing operation from occurring.

The following can help prevent or eliminate boxing:

  1. Use classes instead of structures. This usually involves simply changing the struct keyword to class in the structure definition. This very simple and quick change can dramatically improve performance.

  2. Do not implement explicit interface members on structures. As the discussion shows, this causes the structure to be boxed before the call to an interface member is made through the interface. This reflects the fact that explicit implementation of a method on an interface is only accessible from the interface type. This means that the structure must be cast to that interface type before the explicitly declared methods of that interface type can be used. An interface is a reference type and therefore causes the structure to be boxed when an explicit interface method is accessed on that structure.

Note that changes to a value type that exists in both boxed and unboxed form occur independently of one another.


See Also

See the "Boxing Conversion" and "Unboxing Conversion" topics in the MSDN documentation.

Below is a list of some available profiling tools:

  • Allocation Profiler (free), which can be obtained in the UserSamples section of the web site http://www.gotdotnet.com/community/usersamples/.

  • DevPartner Profiler Community Edition (free), which can be obtained at http://www. compuware .com/products/devpartner/profiler/.

  • DevPartner Studio Professional Edition (purchase), which can be purchased at http://www.compuware.com/products/devpartner/studio/. This package contains the code profiler tool as well as many other tools that work with .NET and other .NET code. This package also contains a memory analysis tool that can aid in debugging performance problems.



C# Cookbook
C# 3.0 Cookbook
ISBN: 059651610X
EAN: 2147483647
Year: 2003
Pages: 315

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net