将方法放在代码中的整体性能

时间:2013-08-24 10:41:57

标签: c#

考虑以下代码:

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秒进行调用。

当我改变方法的位置时,第二种方法花费的时间比第一种方法多!是什么原因?

1 个答案:

答案 0 :(得分:11)

您正在计算琐碎的数量的代码,这样任何数量的微小偶然事件都会干扰结果 - 页面错误或缓存未命中可能会在那时变得相关。 ..而这很容易受到方法排序的影响。

您应该对多个调用进行基准测试 - 或者采取任何方式做足够的工作以花费合理的时间。任何衡量时间不到一秒左右的基准都是可疑的,IMO。

此外:

  • 您几乎肯定不想包含JIT编译时间。
  • JIT编译应该能够删除基本上毫无意义的代码,大部分时间都是如此。我通常添加某种累加器并在测试结束时输出结果(在停止Stopwatch之后)以保持JIT编译器“诚实”。

有关详细信息(以及GC等其他陷阱),请参阅Eric Lippert的基准测试系列: