Will the .NET JIT inline a small function that calls another small function?
I would like to know - will the .NET JITter recursively in开发者_JAVA技巧line small functions called from other small functions?
Just for example:
public static float Square(float value)
{
return value * value;
}
public static float Cube(float value)
{
return Square(value) * value;
}
If I call Cube
from somewhere, will it inline all the way, or will I end up with a function call to Square
?
And, if so, how deep will it recurse to do the inlining? (Say I were crazy enough to implement a Quartic
or Quintic
function in the same way.)
Unfortunately you picked a bad example. The x86 JIT compiler doesn't inline methods that return float. Not 100% sure why, I think it does to avoid consistently problems when the float is converted to an 80-bit floating point value in the FPU. Internal precision is 80-bits but those extra bits are sliced off when the 80-bit value is truncated back to a 32-bit value when it is flushed back to memory. Keeping the value in the FPU too long prevents this truncation from happening and changes the calculation result.
If you replace float by double and compile this code:
static void Main(string[] args) {
Console.WriteLine(Cube(2.0));
}
Then this machine code is generated when the JIT optimizer is enabled:
00000000 push ebp ; setup stack frame
00000001 mov ebp,esp
00000003 call 6DA2BEF0 ; Console.get_Out()
00000008 fld qword ptr ds:[010914B0h] ; ST0 = 8.0
0000000e sub esp,8 ; setup argument for WriteLine
00000011 fstp qword ptr [esp]
00000014 mov ecx,eax ; call Console.Out.WriteLine
00000016 mov eax,dword ptr [ecx]
00000018 call dword ptr [eax+000000D0h]
0000001e pop ebp ; done
0000001f ret
Not only did it inline the functions, it was able to evaluate the expressions at compile time. And directly passes the result by calling Console.WriteLine(8.0). Pretty good huh?
Use double, not float.
精彩评论