简单的方法调用真的很慢?

时间:2012-04-08 19:32:29

标签: c# performance prng

修改:我已解决了我的问题。原因是测试程序出错,一旦我被允许回答我自己的问题,就会详细说明。

我知道通常应该避免这类问题,但我遇到了一个我无法理解的奇怪情况。我一直在尝试实现PRNG,我一直在测试它对System.Random的性能。我发现我的代码慢了~50倍,但问题不是算法,而只是调用方法。即使我刚刚返回一个常量,它仍然会慢很多倍。

所以我写了一个简单的测试程序,它比较调用一个包装random.NextDouble()的方法,一个返回-1的方法,并直接调用random.NextDouble()。我在Ideone中进行了测试,it gave the expected results;所有时间都相似,并且返回常数最快。时间都在0.1秒左右。

但是,在Visual Studio 2011 Beta或2010 C#Express中编译的相同代码将分别为每种情况产生4秒,4秒和0.1秒。我肯定在发布模式下运行,勾选了优化代码复选框,从Visual Studio外部启动会产生相同的结果。那么为什么这样简单的方法在Visual Studio中调用比Ideone慢得多?这是我用来进行基准测试的代码:

using System;
using System.Diagnostics;

public class Test{
    static Random random = new Random();

    public static Double Random() {
        return random.NextDouble();
    }

    public static Double Random2() {
        return -1;
    }

    public static void Main() {
        {
            Stopwatch s = new Stopwatch();
            Double a = 0;
            s.Start();
            for (Int32 i = 0; i < 5000000; i++)
                a += Random();
            s.Stop();
            Console.WriteLine(s.ElapsedMilliseconds);
        }

        {
            Stopwatch s = new Stopwatch();
            Double a = 0;
            s.Start();
            for (Int32 i = 0; i < 5000000; i++)
                a += Random2();
            s.Stop();
            Console.WriteLine(s.ElapsedMilliseconds);
        }

        {
            Stopwatch s = new Stopwatch();
            Double a = 0;
            s.Start();
            for (Int32 i = 0; i < 5000000; i++)
                a += random.NextDouble();
            s.Stop();
            Console.WriteLine(s.ElapsedMilliseconds);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您不应该测量对Random()和Random2()的第一次调用。第一次调用函数时,它由JITTER处理。相反,调用Random()和Random2()一次,然后开始测量。 random.NextDouble()在安装.NET之后就已经编译好了,所以它不会遇到同样的问题。

我不相信这会解释所有的差异,但它应该平衡竞争环境。