2011-01-20 81 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毫秒

看起來邏輯,因爲第二個只是第一個合成糖。但我會使用第二個可讀性。