Почему мой оптимизированный IL дважды хранит одно и то же значение в переменной save?
Исходный код представляет собой цикл for следующим образом:
public class ForLoop
{
public static void Main()
{
var count = 0;
for (var i = 0; i < 10; i = i++)
{
count++;
}
}
}
Я скомпилировал его с включенной оптимизацией (csc /o+ ForLoop.cs
), но у ИЛ есть dup
а затем два stloc.1
и ldloc.1
,
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 22 (0x16)
.maxstack 3
.locals init (int32 V_0,
int32 V_1)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldc.i4.0
IL_0003: stloc.1
IL_0004: br.s IL_0010
IL_0006: ldloc.0
IL_0007: ldc.i4.1
IL_0008: add
IL_0009: stloc.0
IL_000a: ldloc.1
IL_000b: dup
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: stloc.1
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldc.i4.s 10
IL_0013: blt.s IL_0006
IL_0015: ret
} // end of method ForLoop::Main
Инструкции как IL_000b
дублировать i
переменная в моем для цикла. Затем он добавляет 1 к нему, сохраняет результат, так что в стеке остается мое первоначальное значение i
, предварительно доп. Затем он снова сохраняет его и загружает снова.
Это не кажется оптимальным или даже правильным.
Так почему он это делает?
1 ответ
Прежде всего, вы должны понимать, что i++
это на самом деле три операции:
Получить значение
i
Добавьте один к значению и сохраните его.
Вставьте новое значение обратно в
i
,
Во-вторых, ваш код неверен. Ваш цикл имеет i = i++
(а не обычный простой i++
) именно поэтому вы видите дополнительные два задания.
Вы делаете три шага, упомянутых о плюс, сохраняя результат i++
а затем толкать его обратно в i
,