どうすればわかりますか?生成されたコードを見てみましょう。
が
internal static class Program
{
public static int MaxA(int value, int max)
{
return value > max ? max : value;
}
public static int MaxB(int value, int max)
{
if (value > max)
return max;
else
return value;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static int TestA(int a, int b)
{
return MaxA(a, b);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static int TestB(int a, int b)
{
return MaxB(a, b);
}
private static void Main()
{
var rand = new Random();
var a = rand.Next();
var b = rand.Next();
var result = TestA(a, b);
Console.WriteLine(result);
result = TestB(a, b);
Console.WriteLine(result);
}
}
まずは、いくつかのものがまっすぐ取得してみましょう:
は、ここでのテストプログラムです。 リリースビルドでは、MaxA
のILは(Roslynの上)である:
.method public hidebysig static
int32 MaxA (
int32 'value',
int32 max
) cil managed
{
// Method begins at RVA 0x2050
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: bgt.s IL_0006
IL_0004: ldarg.0
IL_0005: ret
IL_0006: ldarg.1
IL_0007: ret
} // end of method Program::MaxA
MaxB
ために、それはです:
.method public hidebysig static
int32 MaxB (
int32 'value',
int32 max
) cil managed
{
// Method begins at RVA 0x2059
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ble.s IL_0006
IL_0004: ldarg.1
IL_0005: ret
IL_0006: ldarg.0
IL_0007: ret
} // end of method Program::MaxB
だから、ILは、両方の機能(それは同じコードだために対称です、分岐命令と分岐命令の順序は逆になります)。
ここで、TestA
とTestB
のx64コードがどのように見えるかを確認しましょう。
TestA
、x64の、RyuJIT:
return MaxA(a, b);
00007FFED5F94530 cmp ecx,edx
00007FFED5F94532 jg 00007FFED5F94538
00007FFED5F94534 mov eax,ecx
00007FFED5F94536 jmp 00007FFED5F9453A
00007FFED5F94538 mov eax,edx
00007FFED5F9453A ret
あなたはMaxA
関数がインライン化されていることがわかりますが(何call
指示がないと、あなたはjg
"ジャンプ大きい場合は"分岐命令をはっきり見ることができます)。
TestB
、x64のは:
return MaxB(a, b);
00007FFED5F94550 cmp ecx,edx
00007FFED5F94552 jle 00007FFED5F94558
00007FFED5F94554 mov eax,edx
00007FFED5F94556 jmp 00007FFED5F9455A
00007FFED5F94558 mov eax,ecx
00007FFED5F9455A ret
当然のことながら、我々は同じ結果を得ます。
compeltenessについては、こちらのx86上のMaxA
です:
return MaxA(a, b);
00A32E22 in al,dx
00A32E23 cmp ecx,edx
00A32E25 jg 00A32E2B
00A32E27 mov eax,ecx
00A32E29 jmp 00A32E2D
00A32E2B mov eax,edx
00A32E2D pop ebp
00A32E2E ret
インラインにも。参考のため
、あなたは分解ウィンドウで生成されたアセンブリコードを確認することができますが、ブレークポイントにしているとき(デバッグ - >解体 - > Windowsの場合)が、最初は必ず抑制するJITをオフにしますモジュールのロードオプションの最適化:
![option to uncheck](https://i.stack.imgur.com/ecWEL.png)
「インライン化は」ジッタオプティマイザは* *メソッドで何をするかにも適用される用語です。 ?:演算子はメソッドではなく、最適化されていないDebugビルドの場合でも、そのマシンコードは常に "インライン"で生成されます。 –
あなたの最大の方法は?確かに、それは非常に小さく、オプティマイザが気に入らないものは何もしません。質問のタイトルを修正する必要があります。 –
@Krythic私はHansに同意します、あなたはタイトルが少し誤解を招いています。 '?:'を含むメソッドがインライン展開されるのではなく、 '?:'演算子自体がインライン展開されているかどうかを尋ねるようなものです。 –