你問:
我不知道,你會更快。
每當你問你應該實際計時並找出答案。
我的目標是測試所有獲得的計數,這些變種:
var enumerable = Enumerable.Range(0, 1000000);
var list = enumerable.ToList();
var methods = new Func<int>[]
{
() => list.Count,
() => enumerable.Count(),
() => list.Count(),
() => enumerable.ToList().Count(),
() => list.ToList().Count(),
() => enumerable.Select(x => x).Count(),
() => list.Select(x => x).Count(),
() => enumerable.Select(x => x).ToList().Count(),
() => list.Select(x => x).ToList().Count(),
() => enumerable.Where(x => x % 2 == 0).Count(),
() => list.Where(x => x % 2 == 0).Count(),
() => enumerable.Where(x => x % 2 == 0).ToList().Count(),
() => list.Where(x => x % 2 == 0).ToList().Count(),
};
我的測試代碼明確每個運行的方法1000次,每個執行時間,一個Stopwatch
措施,並忽略所有結果,其中垃圾收集發生。然後每個方法獲得平均執行時間。
var measurements =
methods
.Select((m, i) => i)
.ToDictionary(i => i, i => new List<double>());
for (var run = 0; run < 1000; run++)
{
for (var i = 0; i < methods.Length; i++)
{
var sw = Stopwatch.StartNew();
var gccc0 = GC.CollectionCount(0);
var r = methods[i]();
var gccc1 = GC.CollectionCount(0);
sw.Stop();
if (gccc1 == gccc0)
{
measurements[i].Add(sw.Elapsed.TotalMilliseconds);
}
}
}
var results =
measurements
.Select(x => new
{
index = x.Key,
count = x.Value.Count(),
average = x.Value.Average().ToString("0.000")
});
下面是結果(下令從最慢到最快):
+---------+-----------------------------------------------------------+
| average | method |
+---------+-----------------------------------------------------------+
| 14.879 |() => enumerable.Select(x => x).ToList().Count(), |
| 14.188 |() => list.Select(x => x).ToList().Count(), |
| 10.849 |() => enumerable.Where(x => x % 2 == 0).ToList().Count(), |
| 10.080 |() => enumerable.ToList().Count(), |
| 9.562 |() => enumerable.Select(x => x).Count(), |
| 8.799 |() => list.Where(x => x % 2 == 0).ToList().Count(), |
| 8.350 |() => enumerable.Where(x => x % 2 == 0).Count(), |
| 8.046 |() => list.Select(x => x).Count(), |
| 5.910 |() => list.Where(x => x % 2 == 0).Count(), |
| 4.085 |() => enumerable.Count(), |
| 1.133 |() => list.ToList().Count(), |
| 0.000 |() => list.Count, |
| 0.000 |() => list.Count(), |
+---------+-----------------------------------------------------------+
兩件事情出來是顯著這裏。
之一,具有內聯.ToList()
任何方法比沒有它的等效顯著慢。
二,LINQ運算符采取的基礎類型的枚舉,在可能情況下,短切的計算的優勢。 enumerable.Count()
和list.Count()
方法顯示了這一點。
還有就是list.Count
和list.Count()
電話沒有什麼區別。因此,關鍵比較在enumerable.Where(x => x % 2 == 0).Count()
和enumerable.Where(x => x % 2 == 0).ToList().Count()
調用之間。由於後者包含額外的操作,我們預計需要更長的時間。它差不多2.5毫秒。
我不知道爲什麼你說你要調用兩次計數的代碼,但如果你做的是更好地建設名單。如果不只是在查詢後執行簡單的.Count()
調用。
這完全取決於'collection'的實際內容。你也可以不計算兩次,而是存儲該數字。 – CodeCaster
我不能因爲在第二個電話我會檢查其他情況。 –
@CodeCaster什麼類型的收集在這裏並不重要。我想你忽略了問題所在。 –