簡體   English   中英

Array.ForEach()與C#中的循環標准相比如何?

[英]How does Array.ForEach() compare to standard for loop in C#?

作為一名C程序員,我可以輸入:

memset( byte_array, '0xFF' );

並獲得一個填充'FF'字符的字節數組。 所以,我一直在尋找替代品:

for (int i=0; i < byteArray.Length; i++)
{
    byteArray[i] = 0xFF;
}

最近,我一直在使用一些新的C#功能,並且一直在使用這種方法:

Array.ForEach<byte>(byteArray, b => b = 0xFF);

當然,第二種方法似乎更清晰,更容易看到,但性能與使用第一種方法相比如何呢? 我是否通過使用Linq和泛型來引入不必要的開銷?

謝謝,戴夫

Array.ForEach<byte>(byteArray, b => b = 0xFF);

這沒有任何作用。 它將每個字節的副本設置為0xFF,它永遠不會在數組中設置。

為了更簡單的方法,您可以嘗試

Enumerable.Repeat((byte)0xFF, someCount).ToArray();

初始化你的數組

重復肯定會慢於你的for循環。 根據CAbbott在評論中發布的鏈接,在一個擁有超過一百萬個項目的陣列上,它慢了大約10.5秒(12.38對1.7),但如果你只用一小部分做了幾次就沒那么大的差別陣列。

您可以編寫一個比Repeat和ToArray更快的簡單方法,因為在開始填充數組之前可以知道數組的長度。

  public static T[] GetPreFilledArray<T>(T fillItem, int count)
  {
       var result = new T[count];
       for(int i =0; i < count; i++)
       {
           result[i] = fillItem;
       }
       return result;
  }

  byte[] byteArray = GetPreFilledArray((byte)0xFF, 1000);

這應該是一個非常快速的選擇,因為它基本上就是你現在正在做的事情。

第二種方法使用委托來設置每個字節,這意味着對數組中的每個字節都有一個方法調用。 設置一個字節只需要很多開銷。

另一方面,普通循環由編譯器很好地優化。 它將確定索引不能在數組之外,因此它將跳過邊界檢查。

澄清一下:你根本就沒有使用LINQ。 ForEach方法是Array類中的一個方法,它早於添加LINQ。

當我想要memset / memcpy類型行為時,我傾向於使用Buffer.BlockCopy 我會測量性能並使用反射器之類的東西。 可能是內部語言調用內置類,而內置類又是MEMCPY和MEMSET的薄包裝器。

如果你的表現就像發布CAbott提到的問題的人那樣,你可能想看看我剛剛在那里發布的答案

除非你在非常嚴格的性能操作中這樣做,否則你不會遇到問題。 關於foreach調用與索引迭代有很多基准測試,差異很小。

當然,你總是可以自己對它進行基准測試......

我不認為仿制葯會對性能產生不利影響。 它們主要在編譯時處理,它們的一般目的是消除在對象和所需類型之間進行轉換的需要,這種類型最不會產生可忽略的影響,並且最多會導致可測量的性能增益。

至於LINQ,我不確定它可以帶來什么性能影響。

但最終,初始化是一項次要任務,性能影響將無關緊要。

我發現如果你把它們放在一個關鍵的執行路徑中,那么Array.ForEach要比for或foreach循環慢得多。 但是,除非您是框架/庫開發人員或實際需要初始化數百萬個數組,否則我根本不擔心性能。 通過在其他地方進行優化,您很可能獲得更多收益。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM