I'm trying to build a code sample để hiển thị tối ưu hóa mã bằng trình biên dịch khi nhân với lũy thừa là 2 số. Tuy nhiên, khi tôi bật mã Optimize trên IL vẫn chủ yếu là như nhau. Bất kỳ ý tưởng những gì tôi đang làm sai ở đây?Khi nào trình biên dịch tối ưu hóa mã của tôi
Mã:
int nr;
int result;
var stopwatch = new Stopwatch();
nr = 5;
stopwatch.Start();
result = nr * 4;
stopwatch.Stop();
Console.WriteLine(result);
Console.WriteLine(stopwatch.Elapsed.ToString() + "ms ellapsed");
stopwatch.Reset();
stopwatch.Start();
result = nr << 2;
stopwatch.Stop();
Console.WriteLine(result);
Console.WriteLine(stopwatch.Elapsed.ToString() + "ms ellapsed");
Non Optimized IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 130 (0x82)
.maxstack 2
.locals init ([0] int32 nr,
[1] int32 result,
[2] class [System]System.Diagnostics.Stopwatch stopwatch,
[3] valuetype [mscorlib]System.TimeSpan CS$0$0000,
[4] valuetype [mscorlib]System.TimeSpan CS$0$0001)
IL_0000: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
IL_0005: stloc.2
IL_0006: ldc.i4.5
IL_0007: stloc.0
IL_0008: ldloc.2
IL_0009: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_000e: ldloc.0
IL_000f: ldc.i4.4
IL_0010: mul
IL_0011: stloc.1
IL_0012: ldloc.2
IL_0013: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0018: ldloc.1
IL_0019: call void [mscorlib]System.Console::WriteLine(int32)
IL_001e: ldloc.2
IL_001f: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed()
IL_0024: stloc.3
IL_0025: ldloca.s CS$0$0000
IL_0027: constrained. [mscorlib]System.TimeSpan
IL_002d: callvirt instance string [mscorlib]System.Object::ToString()
IL_0032: ldstr "ms ellapsed"
IL_0037: call string [mscorlib]System.String::Concat(string,
string)
IL_003c: call void [mscorlib]System.Console::WriteLine(string)
IL_0041: ldloc.2
IL_0042: callvirt instance void [System]System.Diagnostics.Stopwatch::Reset()
IL_0047: ldloc.2
IL_0048: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_004d: ldloc.0
IL_004e: ldc.i4.2
IL_004f: shl
IL_0050: stloc.1
IL_0051: ldloc.2
IL_0052: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0057: ldloc.1
IL_0058: call void [mscorlib]System.Console::WriteLine(int32)
IL_005d: ldloc.2
IL_005e: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed()
IL_0063: stloc.s CS$0$0001
IL_0065: ldloca.s CS$0$0001
IL_0067: constrained. [mscorlib]System.TimeSpan
IL_006d: callvirt instance string [mscorlib]System.Object::ToString()
IL_0072: ldstr "ms ellapsed"
IL_0077: call string [mscorlib]System.String::Concat(string,
string)
IL_007c: call void [mscorlib]System.Console::WriteLine(string)
IL_0081: ret
} // end of method Program::Main
Tối ưu hóa IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 130 (0x82)
.maxstack 2
.locals init ([0] int32 nr,
[1] int32 result,
[2] class [System]System.Diagnostics.Stopwatch stopwatch,
[3] valuetype [mscorlib]System.TimeSpan CS$0$0000,
[4] valuetype [mscorlib]System.TimeSpan CS$0$0001)
IL_0000: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
IL_0005: stloc.2
IL_0006: ldc.i4.5
IL_0007: stloc.0
IL_0008: ldloc.2
IL_0009: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_000e: ldloc.0
IL_000f: ldc.i4.4
IL_0010: mul
IL_0011: stloc.1
IL_0012: ldloc.2
IL_0013: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0018: ldloc.1
IL_0019: call void [mscorlib]System.Console::WriteLine(int32)
IL_001e: ldloc.2
IL_001f: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed()
IL_0024: stloc.3
IL_0025: ldloca.s CS$0$0000
IL_0027: constrained. [mscorlib]System.TimeSpan
IL_002d: callvirt instance string [mscorlib]System.Object::ToString()
IL_0032: ldstr "ms ellapsed"
IL_0037: call string [mscorlib]System.String::Concat(string,
string)
IL_003c: call void [mscorlib]System.Console::WriteLine(string)
IL_0041: ldloc.2
IL_0042: callvirt instance void [System]System.Diagnostics.Stopwatch::Reset()
IL_0047: ldloc.2
IL_0048: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_004d: ldloc.0
IL_004e: ldc.i4.2
IL_004f: shl
IL_0050: stloc.1
IL_0051: ldloc.2
IL_0052: callvirt instance void [System]System.Diagnostics.Stopwatch::Stop()
IL_0057: ldloc.1
IL_0058: call void [mscorlib]System.Console::WriteLine(int32)
IL_005d: ldloc.2
IL_005e: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed()
IL_0063: stloc.s CS$0$0001
IL_0065: ldloca.s CS$0$0001
IL_0067: constrained. [mscorlib]System.TimeSpan
IL_006d: callvirt instance string [mscorlib]System.Object::ToString()
IL_0072: ldstr "ms ellapsed"
IL_0077: call string [mscorlib]System.String::Concat(string,
string)
IL_007c: call void [mscorlib]System.Console::WriteLine(string)
IL_0081: ret
} // end of method Program::Main
Tôi nghĩ trình biên dịch sẽ tối ưu hóa các tuyên bố mul một tuyên bố SHL?
Kiến thức của tôi về IL rất hạn chế (nếu không phải là không tồn tại).
Nếu 'mul' được tối ưu hóa thành' shl' - và tôi không biết nó có hoạt động hay không - nó gần như chắc chắn sẽ được thực hiện khi IL được đưa vào mã nền tảng cụ thể. – LukeH