How to detect boxing/unboxing in code - c#

I'm interested in finding all the places in my solution where boxing or unboxing occur. I know that I can use ildasm like this:
Ildasm.exe yourcomponent.dll /text | findstr box
but I prefer not to look at the MSIL level.
Is there an easy way to do this?

Clr Heap Allocation Analyzer is a free Visual Studio add-on that detects many (but not all) forms of boxing and will highlight your source code and provide a tooltip explanation.
You can also use the Visual Studio Diagnostic Tools to analyze memory allocations. This won't reveal boxing directly, but any time you see a value type on the heap you know it's been boxed (for example, you will see that a references to Int32 takes 12 bytes).

you can do it with FXCOP: (old article with example)
Link - Three Vital FXCop Rules

This is a perfect use case of #Roslyn The Compiler as a Service that is coming out from Microsoft and Jon Skeet as usual is absolutely right. I am writing a book on Roslyn to show how to do these sort of code analytics using Roslyn and top it off with some eye catching visualization by JavaScript.
Here is the code for finding boxing calls. However scope resolution plays a role. But this example should get you started. Pre-order your copy to get more such at https://www.amazon.com/Source-Analytics-Roslyn-JavaScript-Visualization/dp/1484219244?ie=UTF8&Version=1&entries=0
https://gist.github.com/sudipto80/43efdecb878cac17b340cda2c281c3b3

Related

Repeatable builds from same C# source code on different machines

I am trying to produce a tool which is smart enough to programmtically examine release version binaries produced by identical C# code compiled on two seperate machinces at different times and conclude that the code was identical while being able to pick up any code changes if present in the c# code used to produce these binaries.
I have tried using a number of approaches but in order to keep this short i'll just stick to the latest attempt.
I run ildasm with the /text option on the binaries and replace the GUIDs for anonymous fields etc in text, but when the binaries come from different pcs i find that the text produced by ILDASM /text option is reordered. The binaries originating from the same code but compiled by same setup on different machines also appear heavily reordered. Any suggestion how one may be able to control this reordering of IL would be much appreciated ?
Cheers
PS: Any alternative strategies of reliably accomplishing this are also most welcome.
Waiting for Eric Lippert to wake up :) - community wiki out of #mikez 's comment:
When a principal developer (Eric Lippert) on the compiler team speaks, you should listen: http://ericlippert.com/2012/05/31/past-performance-is-no-guarantee-of-future-results/ contains detailed explanation and strong recommendation for not doing it (likely in response to this precise question):
Is compiling the same C# program twice guaranteed to produce the same binary output?
No.
I found that a solution in accordance to what Eric Lippert's mentioned in his post what his client ended up settling for can be reached by setting the processor affinity for the compilation process to 01. After this the executables/ dlls produced are almost identical in excpetion to som mvid and guids used. Running ILDASM on these binaries with the text mode and building a simple hashing tool to strip away this random stuff provides such a solution. I am just providing this for the sake of completion and to help others who may face this problem.

Where can I read up on what the C# compiler does?

Throughout this site I commonly see people answer questions with such answers as "it works like that because the compiler replaces [thing] with [other thing]", so my question is, how do people know/learn this? Where can I learn these things?
The most definitive source for how the C# compiler interprets code is the C# language spec.
http://www.microsoft.com/download/en/details.aspx?id=7029
Also the following blogs provide a lot of more insight into the C# language. Mandatory reading for anyone who wants to become an expert in the language
http://blogs.msdn.com/b/ericlippert/
http://msmvps.com/blogs/jon_skeet/
One technique is to compile your code, and then decompile it using tools such as ILSpy. Using such a tool, you can view the raw IL and see for yourself what the compiler produces.
In addition to the other answers, I'd like to mention that LINQPad is my favorite tool for inspecting IL for quick snippets.
You can type a snippet of code, and immediately see the IL.
It's by far the easiest tool to use, and you can make changes and see the results instantly.
In addition to checking the Intermediate Language and reading the language specification, please allow me to add "CLR via C#" by Jeffrey Richter. Microsoft Press Library of Congress Control Number: 2009943026. This reference is amazing, and goes into complete detail on what's happening under the covers.
Niklaus Wirth's book Compiler Construction (PDF) is an introduction to the theory and the techniques of compiler construction. It gives you a general idea of what a compiler is and what it does.

Is there any C# decompiler that can show the coding almost identically to how it was written?

I've been using reflector to decompile a couple simple c# apps but I notice that though code is being decompiled, I still can't see things as they were written on VS. I think this is the way it is as the compiler replaces human instructions by machine code. However I thought I would give it a try and ask it on here. Maybe there is a decompiler that can decompile and show the coding almost identically to the original code.
That is impossible, since there are lots of ways to get the same IL from different code. For example, there is no way to know if an extension method was called fluent-style vs explicit on the declaring type. There is no way to know if LINQ vs regular code was used. All manner of implicit operations may or may not be there. Removed code may or may not have been there. Many primitives (including enums) up-to-and-including 4 bytes are indistinguishable once they are IL.
If you want the actual code, legally obtain the original code.
Existing .Net decompilers generally decompile to the best of their ability.
You appear to be asking for variable names and line formatting, which for obvious reasons are not compiled to IL.
There are several. I currently use JustDecompile found here http://www.telerik.com/products/decompiler.aspx?utm_source=twitter&utm_medium=sm&utm_campaign=ad
[Edit]
An alternative is .NET Reflector found here: http://www.reflector.net/
I believe there is a free version of it, but didn't take time to look.
Basically, no. There are often many ways to arrive at the same IL code, and there's no way at all for a decompiler to know which was used.
No, nor should there ever be. Things like comments and unreachable code would just add bloat with absolutely zero benefit. The very best you can ever do is approximate the compiled code.

Tools to find boxing in code

Background: I'm developing for the xbox and am at the optomising stage. I need to cut down on object allocations. One place to start is finding out where (un)boxing occurs.
I'm very new to IL (in that i've never looked at any!) and would like to avoid running DLLs through a dissassembler, hunting for the (un)box command then trying to work out what line of code it relates to.
Question: Are there any tools which will report this kind of thing (where (un)boxing occurs) for me?
EDIT: Made request below into its own question since it's fairly distinct from this one.
Many, many, bonus points for a way of tieing a GC heap dump back to lines of code where the object creations occured!!
This MSDN Magazine article details how to create an FxCop (Code Analysis) rule that detects boxing and unboxing and can present violations as a warning. The article is a little on the old side, but you should be able to adapt it to your needs.
There is a tool called BoxCop which does exactly that.
It is not really useful when trying to integrate the checks for boxing/unboxing into the build process. For that you would need some rule for FxCop.

Where can I modify detailed C# compiler optimization settings in Visual Studio?

In Visual Studio C/C++ projects, it's easy to modify compiler's optimization settings in "Property Pages | C/C++ | Optimization". For example, we may give different optimization levels such as /O2 and /O3, as well as advanced optimizations like "Omit Frame Pointers".
However, I can't simply find corresponding UIs in C# project of Visual Studio. All I can find is just turning off optimizations: the "Optimize code" check box is all I've got.
Can C# users control detailed compiler's optimizations like C/C++? Do I have to give compiler options in command line?
Much of the optimisation of C# code goes on at the JIT compiler level, rather than the C# compiler. Basically there are no such detailed settings as the ones available in C or C++.
There are a few performance-related elements of the runtime that can be tweaked, such as GC strategies, but not a great deal.
When I'm building benchmark tests etc from the command line I tend to just use something like this:
csc /o+ /debug- Test.cs
(I believe I have seen the presence of a matching pdb file make a difference to performance, possibly in terms of the cost of exceptions being thrown, hence the debug- switch... but I could be wrong.)
EDIT: If you want to see the difference each bit of optimization makes, there's one approach which could prove interesting:
Compile the same code with and without optimization
Use ildasm or Reflector in IL mode to see what the differences are
Apply the same changes one at a time manually (using ilasm) and measure how much each one has
AFAIK C# compiler has no such detailed optimization properties. Probably optimization is either enabled or disabled.
http://msdn.microsoft.com/en-us/library/6s2x2bzy.aspx
I found just two:
/filealign Specifies the size of sections in the output file.
/optimize Enables/disables optimizations.
A bit OT, but someone looking at this question might find this useful:
Adding this to method signature:
[MethodImpl(MethodImplOptions.NoOptimization)]
turns off compiler optimizations for that method.
See here for details:
https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Categories