2010-04-26 12 views
4

我有一個List<T>,我希望能夠向後複製到一個數組,意味着從List.Count開始,並從列表的末尾開始複製5個項目並向後工作。我可以用簡單的反轉for循環來做到這一點;然而,這樣做可能是一種更快/更有效的方式,所以我想我應該問。我能否以某種方式使用Array.Copy向後複製數組? Array.Copy?

最初我使用的是Queue,因爲它以我需要的正確順序彈出,但我現在需要一次將多個項目彈出到一個數組中,我認爲列表會更快。

+1

「所以我覺得列表會更快。」 - 你有沒有測量性能問題?如果沒有,你是過早地微優化... – 2010-04-26 02:58:35

+0

和過早的優化是萬惡之源(Knuth) – mmr 2010-04-26 02:59:39

+0

不,但使用隊列我只能一次彈出一個,但與列表我可以做一個範圍,在大多數情況下,速度更快。 – daniel 2010-04-26 03:04:18

回答

3

看起來像Array.Reverse有本地代碼用於反轉有時不適用的數組,並且會回退到使用簡單的for循環。在我的測試中,Array.Reverse比簡單的for循環要快得多。在1,000,000個元素陣列反轉1000次的測試中,Array.Reverse約爲600ms,而for-loop約爲800ms。

雖然我不會推薦性能作爲使用Array.Reverse的理由。這是一個非常小的差別,你會在將它加載到List中的那一刻失去它,它將再次遍歷數組。無論如何,在對應用進行概要分析並確定性能瓶頸之前,您不應該擔心性能。

public static void Test() 
    { 
     var a = Enumerable.Range(0, 1000000).ToArray(); 

     var stopwatch = Stopwatch.StartNew(); 

     for(int i=0; i<1000; i++) 
     { 
      Array.Reverse(a); 
     } 

     stopwatch.Stop(); 

     Console.WriteLine("Elapsed Array.Reverse: " + stopwatch.ElapsedMilliseconds); 

     stopwatch = Stopwatch.StartNew(); 

     for (int i = 0; i < 1000; i++) 
     { 
      MyReverse(a); 
     } 

     stopwatch.Stop(); 

     Console.WriteLine("Elapsed MyReverse: " + stopwatch.ElapsedMilliseconds); 
    } 

    private static void MyReverse(int[] a) 
    { 
     int j = a.Length - 1; 
     for(int i=0; i<j; i++, j--) 
     { 
      int z = a[i]; 
      a[i] = a[j]; 
      a[j] = z; 
     } 
    } 
+0

我認爲它是一個巨大的性能瓶頸。目前,我們正在提取一個結果並逐個將其提交給一個數據庫,但我會一次性提交一個範圍,但它需要按順序排列。這就是我爲什麼這樣做。 – daniel 2010-04-26 03:19:27

+5

@daniel,但我認爲瓶頸是一次對數據庫執行一個查詢,而不是顛倒數組。 – 2010-04-26 03:22:20

+0

是真的,當時沒有想到xD – daniel 2010-04-26 03:24:04

1

不可能比簡單的for循環做得更快。

0

您可以通過多種方式實現它,但最快的方法是以完全按照您的方式獲取元素。你可以使用Array.Reverse,Array.Copy等,或者你可以使用LINQ和擴展方法,它們都是有效的選擇,但它們不應該更快。

0

在您的意見之一:

目前,我們正處在一個時間

拉出一個結果,並提交到一個數據庫中的一個之間有一個很大的區別使用for循環向後遍歷List<T>並一次將記錄提交到數據庫。前者很好,沒有人贊同後者。

爲什麼不只是迭代 - 填充一個數組 - 然後發送數組到數據庫中,全部填充?

var myArray = new T[numItemsYouWantToSend]; 

int arrayIndex = 0; 
for (int i = myList.Count - 1; arrayIndex < myArray.Length; --i) { 
    if (i < 0) break; 
    myArray[arrayIndex++] = myList[i]; 
} 

UpdateDatabase(myArray);