开发者

How can I verify if a function has been cached in C#?

I have created the following functions in C#:

float GetPI()
{
  return 22.0f/7.0f;
}

void Calculate()
{
  float f1 = GetPI()*4;
  float f2 = GetPI()*5;
}

If I create a release build, how will I be able to verify whether the JIT compiler will cache the 22/7 calculation, or whether it will be calculated each time the function GetPI is called?

PS : I do not have visual C# studio professional edition

EDIT : changed 开发者_StackOverflow中文版22/7 to 22.0f/7.0f to make the example function more accurate


I'm not sure what you mean by being cached. Unless the compiler doesn't do any constant folding (which it will in this case) or the runtime doesn't inline your function (which it probably would in this case), it will not do any "caching" automatically for you.


The expression 22f/7f is a constant expression and can be evaluated at compile time (aka, constant folding). So in the compiled assembly, it will appear as:

float GetPI()
{
  return 3.142857f; // however many digits of precision
}

The compiler will always make this kind of optimization if given the opportunity. Unless there's a compiler option to disable this (which I'm not sure there is). To verify this happens, you could use Reflector (as the others have pointed out) to see the compiled assembly. You should see that it does indeed do this whether it is Debug or Release builds or using the express versions (unless this optimization is explicitly disabled).


If the function is simple enough, the runtime might inline your function call. So rather than calling this function, it will insert the result in place of the function call. Seeing as this is just a function to just return some number, it will probably will do this optimization. I don't know if there even is a way to see if this happens without actually seeing the JIT compiled code through a debugger.


If you mean caching as in memoization, then no this will not be done automatically and you'll have to do this yourself.


If you want an absolute guarantee that the compiler will "cache" (as in not recalculate the quotient) the value, you should declare your value as a constant (or use the existing and more accurate System.Math.PI constant). Nothing is being determined at runtime, everything is known at compile time. And every time you use this value, it will be "inlined" so you won't have to worry about that.

const float PI = 22f / 7f; // will be stored as 3.142857f

// or another way, if you need PI to be a float but want a more accurate value
const float PI = (float)Math.PI; // will store as much precision possible
// note that this only works because Math.PI is declared as a constant


Download and install .NET Reflector (originally written by Lutz Roeder, and now maintained by Red Gate). You may have to look for an older version if you don't want to pay.

When you open your code in Reflector, you can see what changes the compiler made.

This wouldn't show you JIT optimizations, you need to step through the machine code in a debugger for that, but I'm pretty sure this case will be evaluated by the C# compiler.


There are many ways. One convenient is using .NET Reflector.

Open up your assembly in Reflector, select C#, find the method in the treeview, select Tools/Disassemble. The disassembler will show something like the following:

public float GetPI()
{
    return 3f;
} 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜