views:

535

answers:

5

I want to do some benchmarking of a C# process, but I don't want to use time as my vector - I want to count the number of IL instructions that get executed in a particular method call. Is this possible?

Edit I don't mean static analysis of a method body - I'm referring to the actual number of instructions that are executed - so if, for example, the method body includes a loop, the count would be increased by however many instructions make up the loop * the number of times the loop is iterated.

+1  A: 

Well, it won't be easy. I think you could instrument your assembly post-compile with performance counter code that executed after blocks of IL. For example, if you had a section of a method that loaded an int onto the stack then executed a static method using that int under optimized code, you could record a count of 2 for the int load and call.

Even using existing IL/managed assembly reading/writing projects, this would be a pretty daunting task to pull off.

Of course, some instructions that your counter recorded might get optimized away during just-in-time compiling to x86/ia64/x64, but that is a risk you'd have to take to try to profile based on an abstract lanaguage like IL.

ZeroBugBounce
Are the any existing projects / frameworks that would be up to the task?
Erik Forbes
Don't know of anything that does what you are want. I have edited IL by round-tripping C# assemblies with ILDASM/ILASM and I know the PostSharp project has post-compile IL weaving - and as OSS it would be good place to look to see how someone has already solved the problem: http://www.postsharp.org
ZeroBugBounce
wow post sharp is cool ... been looking for something like it for ages
Sam Saffron
+1  A: 

You could use ICorDebug which has a managed interface. Chuck a break point at the beginning of the method and programmaticly step through the code till it leaves the method.

However, I am not sure how useful the metric will be, people tend to use time for this kind of stuff. Some IL instructions are more expensive than others.

Sam Saffron
Mmm, great idea - I hadn't even considered using the existing debugging interfaces... And you're right - IL instructions have varying costs - but in theory with this approach I could time each one individually as the debugger stepped through them. Thanks, I'll give this a try! =)
Erik Forbes
On second thought I don't know if this would be my solution - I'd be forced to run the code I want to analyze in a separate process. This introduces a lot of complexity into the process of writing the code I'm analyzing, and I don't want to expose that complexity. Hmmm...
Erik Forbes
A: 

I use the Code Metrics add in to Reflector

The CodeMetrics add-in analyses and computes several code quality metrics on your assemblies. This add-in uses Reflector to compute classic metrics such as cyclomatic complexity or more straightforward ones such as the number of local variables in a method. All results can be saved to a file.

Install the plugin. Select an assembly and load method metrics. It will show you a grid with CodeSize, CyclomaticComplexity, # of Instruction, etc.

jop
Meh - I'm referring to runtime instructions executed, not a static analysis of a method.
Erik Forbes
+2  A: 

I don't think it's possible to do what you want. This is because the IL is only used during JIT (Just-In-Time) compilation. By the time the method is running the IL has been translated into native machine code. So, while it might be possible to count the number of IL instructions in a given method/type/assembly statically, there's no concept of this at runtime.

You haven't stated your intention in knowing the number of IL instructions that would be interpreted. Given that there's only a loose correlation between the IL count of a method body and the actual number of machine code instructions, I fail to see what knowing this number would achieve (other than satisfying your curiosity).

Drew Noakes
A: 

I know you don't want the static count. However, the static IL count per arc, plus the number of times the arc was executed together give you the IL count. You'd need to instrument each arc for this, which requires inserting a counter.

(An arc is a sequence of instructions which you can't jump in or out. If you execute the first instruction, you'll always execute the last, etc.)

MSalters