C# Count() Extension Method Performance
如果在具有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace CountSpeedTest { // Output: // List - CLR : 0 ms // Enumerate - CLR : 10 ms // List - Mine: 12 ms // Enumerate - Mine: 12 ms class Program { private const int Runs = 10; private const int Items = 1000000; static void Main(string[] args) { var total = new long[] {0, 0, 0, 0}; for (int i = 0; i < Runs; ++i) { var items = Enumerable.Range(0, Items).Select(o => o.ToString()).ToList(); var list = new List<string>(items); var enumerate = new Enumerate<string>(items); total[0] += TimeCount(list, c => c.Count()); total[1] += TimeCount(enumerate, c => c.Count()); total[2] += TimeCount(list, c => c.SlowCount()); total[3] += TimeCount(enumerate, c => c.SlowCount()); } Console.WriteLine(String.Format("List - CLR : {0} ms", total[0] / Runs)); Console.WriteLine(String.Format("Enumerate - CLR : {0} ms", total[1] / Runs)); Console.WriteLine(String.Format("List - Mine: {0} ms", total[2] / Runs)); Console.WriteLine(String.Format("Enumerate - Mine: {0} ms", total[3] / Runs)); Console.ReadKey(true); } private static long TimeCount<T>(IEnumerable<T> collection, Func<IEnumerable<T>, int> counter) { var stopwatch = Stopwatch.StartNew(); var count = counter(collection); stopwatch.Stop(); if (count != Items) throw new Exception("Incorrect Count"); return stopwatch.ElapsedMilliseconds; } } public static class CountExtensions { // Performs a simple enumeration based count. public static int SlowCount<T>(this IEnumerable<T> items) { var i = 0; var enumerator = items.GetEnumerator(); while (enumerator.MoveNext()) i++; return i; } } // Wraps an IEnumerable<T> to hide its Count property. public class Enumerate<T> : IEnumerable<T> { private readonly IEnumerable<T> collection; public Enumerate(IEnumerable<T> collection) { this.collection = collection; } public IEnumerator<T> GetEnumerator() { return collection.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } } |
关于一个相关的说明:实现
它不按名称查找
If the type of source implements
ICollection , that
implementation is used to obtain the
count of elements. Otherwise, this
method determines the count.
(显然,这只适用于不带谓词的重载。)
因此,如果您希望有效地获得计数,请确保实现
是的,Enumerable.Count方法确实会查找
但只有在使用不带其他参数的Count扩展方法时,这才是正确的。如果使用带谓词的版本,它将遍历可枚举元素。