c# - 为什么在这个简单的测试中,方法的速度与触发顺序有关?

标签 c# performance

我一直在做其他实验,直到这种奇怪的行为引起了我的注意。

代码在 x64 版本中编译。

如果键入 1,List 方法的第 3 次运行比前 2 次多花费 40% 的时间。输出是

List costs 9312
List costs 9289
Array costs 12730
List costs 11950

如果键入 2,Array 方法的第 3 次运行比前 2 次多花费 30% 的时间。输出是

Array costs 8082
Array costs 8086
List costs 11937
Array costs 12698

可以看到模式,完整的代码附在下面(编译运行即可): {提供的代码对于运行测试来说是最少的。用于获得可靠结果的实际代码更复杂,我包装了该方法并在适当预热后对其进行了 100 多次测试

class ListArrayLoop
{
    readonly int[] myArray;
    readonly List<int> myList;
    readonly int totalSessions;

    public ListArrayLoop(int loopRange, int totalSessions)
    {
        myArray = new int[loopRange];
        for (int i = 0; i < myArray.Length; i++)
        {
            myArray[i] = i;
        }
        myList = myArray.ToList();
        this.totalSessions = totalSessions;
    }
    public  void ArraySum()
    {
        var pool = myArray;
        long sum = 0;
        for (int j = 0; j < totalSessions; j++)
        {
            sum += pool.Sum();
        }
    }
    public void ListSum()
    {
        var pool = myList;
        long sum = 0;
        for (int j = 0; j < totalSessions; j++)
        {
            sum += pool.Sum();
        }
    }

}
class Program
{
    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        ListArrayLoop test = new ListArrayLoop(10000, 100000);

        string input = Console.ReadLine();


        if (input == "1")
        {
            sw.Start();
            test.ListSum();
            sw.Stop();
            Console.WriteLine("List costs {0}",sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ListSum();
            sw.Stop();
            Console.WriteLine("List costs {0}", sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ArraySum();
            sw.Stop();
            Console.WriteLine("Array costs {0}", sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ListSum();
            sw.Stop();
            Console.WriteLine("List costs {0}", sw.ElapsedMilliseconds);
        }
        else
        {
            sw.Start();
            test.ArraySum();
            sw.Stop();
            Console.WriteLine("Array costs {0}", sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ArraySum();
            sw.Stop();
            Console.WriteLine("Array costs {0}", sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ListSum();
            sw.Stop();
            Console.WriteLine("List costs {0}", sw.ElapsedMilliseconds);
            sw.Reset();
            sw.Start();
            test.ArraySum();
            sw.Stop();
            Console.WriteLine("Array costs {0}", sw.ElapsedMilliseconds);
        }

        Console.ReadKey();
    }
}

最佳答案

人为的问题会给你人为的答案。

优化应该在代码编写之后而不是之前完成。以最容易理解和维护的方式编写您的解决方案。然后,如果程序对于您的用例来说不够快,那么您可以使用 profiling tool然后回头看看真正的瓶颈在哪里,而不是你“认为”的地方。

人们在您的情况下尝试进行的大多数优化都是花费 6 小时来做一些可以将运行时间减少 1 秒的事情。大多数小程序的运行次数不足以抵消您尝试“优化”它所花费的成本。


话虽这么说,但这是一个奇怪的边缘案例。我对其进行了一些修改,并通过探查器运行它,但我需要降级我的 VS2010 安装,这样我才能获得 .NET 框架源代码。


我使用更大的示例运行了探查器,我找不到需要更长时间的充分理由。

关于c# - 为什么在这个简单的测试中,方法的速度与触发顺序有关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10126460/

相关文章:

c# - 在 WebView Metro Style 应用程序中加载本地 html 文件

c# - 欧拉计划解决方案 #14

c# - 无法从 'localStorage' 读取 'Window' 属性

javascript - 有没有办法减少 ExtJS 的冗长

multithreading - Haskell:次优的并行 GC 工作平衡,并行执行没有加速

c# - 使用 ScriptManager.RegisterStartupScript 从代码后面调用 javascript 方法

c# - 使用给定基类创建派生类

performance - 甲骨文 : table with unused columns impact performance?

c# - 为什么以下代码在 WCF 服务与控制台应用程序中运行速度相当慢?

python - 从一个非常大的二进制文件中有效地读取几行