Почему такая разница в IL между IF и условным оператором?

C # имеет условный оператор и операторы IF и Я подозревал, что условный оператор будет просто синтаксическим сахаром. Таким образом, во время компиляции он будет таким же, как и операция IF.

Однако они этого не делают (см. ниже), у них разные ИЛ. Попытка обернуть голову вокруг этого, и у меня есть предположение, что это - оптимизация производительности, которую получает условный оператор, потому что это ограниченная область действия.

Хотелось бы узнать, верно ли мое предположение или нет, и, может быть, есть что-то еще?

Также в IL IF есть несколько проверок (L_000c, L_000d, L_000f) вокруг значений int, которые я не могу понять смысл. Это то, что заставляет меня думать, что это более надежное решение за счет производительности из-за более широкой области применения.


Код для IF
var result = "";
if (Environment.Is64BitOperatingSystem)
{
    result = "Yes";
}
else
{
    result = "No";
}
Console.WriteLine(result);

Код для условного оператора (я понимаю различия, но независимо от того, как я его изменяю - присваиваю переменную и т. д., это очень мало меняет)

Console.WriteLine("Is the OS x64? {0}", Environment.Is64BitOperatingSystem ? "Yes" : "No");

IL для IF

L_0001: ldstr ""
L_0006: stloc.0 
L_0007: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
L_000c: ldc.i4.0 
L_000d: ceq 
L_000f: stloc.2 
L_0010: ldloc.2 
L_0011: brtrue.s L_001d
L_0013: nop 
L_0014: ldstr "Yes"
L_0019: stloc.0 
L_001a: nop 
L_001b: br.s L_0025
L_001d: nop 
L_001e: ldstr "No"
L_0023: stloc.0 
L_0024: nop 
L_0025: ldloc.0 
L_0026: call void [mscorlib]System.Console::WriteLine(string)

IL для условного

L_002c: ldstr "Is the OS x64? {0}"
L_0031: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
L_0036: brtrue.s L_003f
L_0038: ldstr "No"
L_003d: br.s L_0044
L_003f: ldstr "Yes"
L_0044: call void [mscorlib]System.Console::WriteLine(string, object)
c# il
7 голосов | спросил Robert MacLean 5 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 05 Sep 2011 17:41:28 +0400 2011, 17:41:28

1 ответ


0

, если

IL_0000:  call       bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
IL_0005:  brfalse.s  IL_000f
IL_0007:  ldstr      "Yes"
IL_000c:  stloc.0                  // <------ Difference 1
IL_000d:  br.s       IL_0015
IL_000f:  ldstr      "No"
IL_0014:  stloc.0
IL_0015:  ldloc.0
IL_0016:  call       void [mscorlib]System.Console::WriteLine(string)

? (троичный оператор )

IL_001b:  call       bool [mscorlib]System.Environment::get_Is64BitOperatingSystem()
IL_0020:  brtrue.s   IL_0029
IL_0022:  ldstr      "No"          // <------ Difference 2
IL_0027:  br.s       IL_002e
IL_0029:  ldstr      "Yes"
IL_002e:  stloc.0
IL_002f:  ldloc.0
IL_0030:  call       void [mscorlib]System.Console::WriteLine(string)

(почти) один и тот же код для обоих в режиме выпуска. if добавляет второй stdloc.0, который не является не оптимизирован компилятором. И другое отличие состоит в том, что true и false инвертированы.

(поэтому я узнаю, что ВСЕГДА должен запускать WinMerge!)

И это был бы интересный вопрос. Почему они перевернуты? Есть ли логика?

ответил xanatos 5 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 05 Sep 2011 17:51:32 +0400 2011, 17:51:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132