![](/img/trans.png)
[英]Why does using IEnumerable<T> inside a recursive method make it much slower than using a List<T>?
[英]Why does a simple List<T> seem to be slower than an ArrayList?
出於好奇,我想測試將GenericList與ArrayList進行比較的刻度數。
對於下面的代碼,當我檢查秒表時,ArrayList似乎更快。
我做錯了還是有解釋? (我相信List會更快)
測試代碼和輸出如下 :
private static void ArrayListVsGenericList()
{
// Measure for ArrayList
Stopwatch w0 = new Stopwatch();
w0.Start();
ArrayList aList = new ArrayList();
for (int i = 0; i < 1001; i++)
{
Point p = new Point();
p.X = p.Y = i;
aList.Add(p);
}
foreach (Point point in aList)
{
int v0 = ((Point) aList[8]).X; //unboxing
}
w0.Stop();
// Measure for Generic List<Point>
Stopwatch w1 = new Stopwatch();
w1.Start();
List<Point> list = new List<Point>();
for (int i = 0; i < 1001; i++)
{
Point p = new Point();
p.X = p.Y = i;
list.Add(p);
}
foreach (var point in list)
{
int v1 = list[8].X;
}
w1.Stop();
Console.WriteLine("Watch 0 : " + w0.ElapsedTicks);
Console.WriteLine("Watch 1 : " + w1.ElapsedTicks);
Console.WriteLine("Watch 0 > Watch 1 : " + (w0.ElapsedTicks > w1.ElapsedTicks));
}
更改測試程序以至少運行兩次方法並忽略第一次運行。 結果是由具體類型List<Point>
的代碼生成和jitting引起的。
在我的機器上,這導致以下輸出:
Watch 0 : 154
Watch 1 : 74
Watch 0 > Watch 1 : True
這幾乎是人們所期望的。
你沒有消除像JIT這樣的第一個執行效果。 需要為每個值類型參數編譯一次泛型。
ArrayList
已經使用ngen進行了預編譯。
List<T>
僅針對某些參數類型進行了預編譯(我讀過核心庫實例化了常見參數的一些最重要的泛型,如object,bool,int,...),如果有的話。 所以它會產生一次性費用。
您還應該注意, ArrayList
大部分性能成本都是間接的:拳擊給GC帶來了更大的壓力,並且使用了更多的內存。 但是你的測試不會衡量。 產生更多垃圾的成本還取決於存在多少其他對象以及對象的生命周期。
在編寫測試時,您應該在實際測試之前執行一次所有代碼,或者使用那么多迭代,一次成本可以忽略不計。 使用發布版本並在沒有附加調試器的情況下運行也很重要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.