Я просто пытаюсь попасть в ИЛ, потому что я работаю с инъекцией кода. Я должен анализировать код и охватывать различные случаи.ИЛ-сравнение наоборот
К сожалению, это не работает, чтобы вставить вызов метода в конце, если последние инструкции находятся внутри if-предложения, потому что тогда вызов содержится в paranthesis.
Теперь я анализирую if-код, переводяемый в IL, и я немного смущен тем, как это делается. Очевидно, компилятор меняет if. Это из-за соображений производительности? Если да, то насколько это улучшает производительность?
Смотрите сами:
string test;
Random rnd = new Random();
bool b = rnd.Next(0, 10) == 3;
if (b)
{
// TRUE
test = "True branch";
// END TRUE
}
else
{
// FALSE
test = "False branch";
//END FALSE
}
и это выход:
IL_0000: nop
IL_0001: newobj instance void [mscorlib]System.Random::.ctor()
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.0
IL_0009: ldc.i4.s 10
IL_000b: callvirt instance int32 [mscorlib]System.Random::Next(int32, int32)
IL_0010: ldc.i4.3
IL_0011: ceq
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: ldc.i4.0
IL_0016: ceq
IL_0018: stloc.3
IL_0019: ldloc.3
IL_001a: brtrue.s IL_0026
IL_001c: nop
IL_001d: ldstr "True branch"
IL_0022: stloc.0
IL_0023: nop
IL_0024: br.s IL_002e
IL_0026: nop
IL_0027: ldstr "False branch"
IL_002c: stloc.0
IL_002d: nop
IL_002e: ret
Как вы можете видеть, после сравнения случайного результата с сопзЬ 3 он делает Comparision против 0 снова и таким образом отменяет результат, который эквивалентен if (false)
.
Какая у этого причина? Разве это не так результативно, так как вам нужны дополнительные инструкции? Всегда ли это происходит?
Вы смотрите версию отладки. Измените его на версию выпуска, и он использует 'brfalse.s' – xanatos
. Нет' 'cne', поэтому может быть использовано' ceq'; но тогда возникает вопрос, почему «brfalse» вместо «brtrue» в RELEASE. Оба сравнивают флаг и будут JIT до одной инструкции почти во всех наборах инструкций CPU. В этом случае, вероятно, это был просто выбор, который в какой-то момент сделал один блок кода для создания одного типа сравнения вместо кода для выбора между двумя разными типами сравнения. Я не верю, что есть ответ на этот вопрос. –
@Peter Технически версия Debug добавляет четыре инструкции и дополнительное местоположение стека IL_0015, IL_0016, IL_0018, IL_0019 и расположение стека .3, но, будучи инструкциями Debug IL, я думаю, что это не настоящая проблема. В то время как JITting они могут быть сопоставлены с образцом и удалены – xanatos