考虑以下代码:
namespace FastReflectionTests
{
public class Test
{
public void Method1()
{
var x = 10;
var y = 20;
if (x == 10 && y == 20)
{
}
}
public void Method2()
{
var x = 10;
var y = 20;
if (x == 10 && y == 20)
{
}
}
}
}
现在考虑IL代码:
这是方法1:
instance void Method1 () cil managed
{
// Method begins at RVA 0x3bd0
// Code size 17 (0x11)
.maxstack 2
.locals init (
[0] int32 x,
[1] int32 y
)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldc.i4.s 20
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldc.i4.s 10
IL_0009: bne.un.s IL_0010
IL_000b: ldloc.1
IL_000c: ldc.i4.s 20
IL_000e: pop
IL_000f: pop
IL_0010: ret
} // end of method Test::Method1
这是方法2:
instance void Method2 () cil managed
{
// Method begins at RVA 0x3bf0
// Code size 17 (0x11)
.maxstack 2
.locals init (
[0] int32 x,
[1] int32 y
)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldc.i4.s 20
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldc.i4.s 10
IL_0009: bne.un.s IL_0010
IL_000b: ldloc.1
IL_000c: ldc.i4.s 20
IL_000e: pop
IL_000f: pop
IL_0010: ret
} // end of method Test::Method2
方法1获取调用00:00:00.0000019秒。
方法2获取00:00:00.0000006秒进行调用。
我为测试编写了这段代码
public class Program
{
private static void Main(string[] args)
{
var test = new Test();
test.Method1();
test.Method2();
System.Console.ReadLine();
}
}
public class Test
{
public void Method1()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var x = 10;
var y = 20;
if (x == 10)
{
if (y == 20)
{
}
}
stopwatch.Stop();
Console.WriteLine("Time Method1: {0}",
stopwatch.Elapsed);
}
public void Method2()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var x = 10;
var y = 20;
if (x == 10 && y == 20)
{
}
stopwatch.Stop();
Console.WriteLine("Time Method2: {0}",
stopwatch.Elapsed);
}
}
我改变了method1和method2的位置。
test.Method2();
test.Method1();
并重新进行测试。
method1 get 00:00:00.0000006秒进行调用。
方法2获取00:00:00.0000019秒进行调用。
当我改变方法的位置时,第二种方法花费的时间比第一种方法多!是什么原因?
答案 0 :(得分:11)
您正在计算琐碎的数量的代码,这样任何数量的微小偶然事件都会干扰结果 - 页面错误或缓存未命中可能会在那时变得相关。 ..而这很容易受到方法排序的影响。
您应该对多个调用进行基准测试 - 或者采取任何方式做足够的工作以花费合理的时间。任何衡量时间不到一秒左右的基准都是可疑的,IMO。
此外:
Stopwatch
之后)以保持JIT编译器“诚实”。有关详细信息(以及GC等其他陷阱),请参阅Eric Lippert的基准测试系列: