2011-01-20 46 views
4

以下代码提供了两种方法,用于生成总和小于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.在整篇文章所,笔者更关注的语法,紧凑性和代码的可读性,但支付对表现的关注很少,几乎没有讨论过。

所以我基本上想知道,哪种方法更快?性能方面通常更好(通常):查询语法或手动循环?

请详细讨论它们,如果有的话提供参考。 :-)

+1

查询必须在某个时间点转入循环,因此即使差异可忽略不计,也必定会有一些开销。 – 2011-01-20 19:31:28

+0

只是好奇心,你能解释这个顺序吗?: orderby(x * x + y * y)降 我不明白它是如何工作的 – Notter 2011-01-20 19:37:06

+1

第二个会快很多,因为它没有做任何事情但建立一个查询后,做一个ToList()你将能够比较;) – Guillaume86 2011-01-20 19:41:29

回答

9

分析是事实,但我的直觉是循环可能更快。重要的是,100倍的性能差异中的99倍在事物的宏伟计划中并不重要。使用更易读的版本,当您需要稍后维护时,您的未来自我会感谢您。

1

虽然这并不严格回答你的问题,性能明智的,我建议合并是x + y的逻辑到迭代,从而:

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

运行的每个函数1000次:

为循环:2623毫秒 查询:2821毫秒

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