Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 哪一个比较快:查询语法与循环_C#_Performance_Loops_Code Readability_Linq Query Syntax - Fatal编程技术网

C# 哪一个比较快:查询语法与循环

C# 哪一个比较快:查询语法与循环,c#,performance,loops,code-readability,linq-query-syntax,C#,Performance,Loops,Code Readability,Linq Query Syntax,下面的代码提供了两种生成总和小于100的整数对的方法,它们根据与0,0的距离按降序排列 //approach 1 private static IEnumerable<Tuple<int,int>> ProduceIndices3() { var storage = new List<Tuple<int, int>>(); for (int x = 0; x < 100; x++)

下面的代码提供了两种生成总和小于100的整数对的方法,它们根据与0,0的距离按降序排列

    //approach 1
    private static IEnumerable<Tuple<int,int>>  ProduceIndices3()
    {
        var storage = new List<Tuple<int, int>>();
        for (int x = 0; x < 100; x++)
        {
            for (int y = 0; y < 100; y++)
            {
                if (x + y < 100)
                    storage.Add(Tuple.Create(x, y));
            }
        }
        storage.Sort((p1,p2) =>
           (p2.Item1 * p2.Item1 + 
           p2.Item2 * p2.Item2).CompareTo(
           p1.Item1 * p1.Item1 +
           p1.Item2 * p1.Item2));
        return storage;
    }

    //approach 2
    private static IEnumerable<Tuple<int, int>> QueryIndices3()
    {
        return from x in Enumerable.Range(0, 100)
               from y in Enumerable.Range(0, 100)
               where x + y < 100
               orderby (x * x + y * y) descending
               select Tuple.Create(x, y);
    }
本代码摘自比尔·瓦格纳的《有效C》一书第8项。在整篇文章中,作者更多地关注代码的语法、紧凑性和可读性,但很少关注性能,几乎没有讨论它

所以我基本上想知道,哪种方法更快?通常性能更好的是什么:查询语法还是手动循环


请详细讨论,如有,请提供参考:-

分析是事实,但我的直觉是循环可能更快。重要的是,100次中有99次的性能差异在总体方案中并不重要。使用更具可读性的版本,当您以后需要维护它时,您未来的自我将感谢您。

虽然这并不能严格回答您的问题,但从性能角度来看,我建议将x+y逻辑合并到迭代中,因此:

for (int x = 0; x < 100; x++)
    for (int y = 0; y < 100 - x; y++)
        storage.Add(Tuple.Create(x, y));

每个函数运行1000次:

循环频率:2623毫秒 查询:2821MS


看起来很有逻辑,因为第二个只是第一个的合成糖。但是我会使用第二个,因为它的可读性。

查询必须在某个点上转移到循环中,所以一定会有一些开销,即使差异可以忽略不计。出于好奇,你能解释一下这种排序吗?:orderby x*x+y*y降序我不明白它是如何工作的第二个会快得多,因为它除了构建查询之外什么都不做,所以在做了ToList之后,您将能够进行比较;诺特:这是距离0clever的距离,但它会使速度与需要更改的其他函数的比较产生偏差:从Enumerable.Range0中的y开始,100 xIn老实说,任何半体面的优化编译器都应该使此更改可以忽略不计。如果我可以补充,在第二种方法中,编译器可以更好地理解代码的目的,因此,它可以更恰当地对其进行优化。也许现在,即使进行了优化,第一种方法也会运行得更快,然而,在不久的将来,我们可能会从第一种方法中获得更好的性能。对于一个小型学习项目来说,评测可能有点过火。把数字从100增加到1000000是很容易的,只是用秒表来测量时间上的差异。@菲尔-我会考虑分析,即使你没有使用一个花哨的工具来做。出于好奇,当你把它画出来的时候,您是否确实从第二个函数中枚举了查询,例如使用.ToList或其他什么?如果使用ToList,则大约需要3毫秒;