[英]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.