Is the Linq Count() faster or slower than List.Count or Array.Length?
Linq Count(
)方法是否比List<>.Count
或Array.Length
更快或更慢?
In general Slower. LINQ's Count in general is an O(N)
operation while List.Count
and Array.Length
are both guaranteed to be O(1)
.
However it some cases LINQ will special case the IEnumerable<T>
parameter by casting to certain interface types such as IList<T>
or ICollection<T>
. It will then use that Count method to do an actual Count()
operation. So it will go back down to O(1)
. But you still pay the minor overhead of the cast and interface call.
Enumerable.Count()
方法使用.Count
检查ICollection<T>
- 所以对于数组和列表来说,效率并不是非常低效(只是额外的间接级别)。
Marc has the right answer but the devil is in the detail.
On my machine:
IList<T>
Arrays start off slower since .Length involves only a single operation, .Count on arrays involves a layer of indirection. So .Count on arrays starts off 10x slower (on my machine), which could be one of those reasons the interface is implemented explicitly. Imagine if you had an object with two public properties, .Count and .Length. Both do the exact same thing but .Count is 10X slower.
Of course non of this really makes much of a difference since you would have to be counting your arrays and lists millions of times a second to feel a performance hit.
Code:
static void TimeAction(string description, int times, Action func) {
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < times; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
var array = Enumerable.Range(0, 10000000).ToArray();
var list = Enumerable.Range(0, 10000000).ToArray().ToList();
// jit
TimeAction("Ignore and jit", 1 ,() =>
{
var junk = array.Length;
var junk2 = list.Count;
array.Count();
list.Count();
});
TimeAction("Array Length", 1000000, () => {
var tmp1 = array.Length;
});
TimeAction("Array Count()", 1000000, () =>
{
var tmp2 = array.Count();
});
TimeAction("Array Length through cast", 1000000, () =>
{
var tmp3 = (array as ICollection<int>).Count;
});
TimeAction("List Count", 1000000, () =>
{
var tmp1 = list.Count;
});
TimeAction("List Count()", 1000000, () =>
{
var tmp2 = list.Count();
});
Console.ReadKey();
}
Results:
Array Length Time Elapsed 3 ms Array Count() Time Elapsed 264 ms Array Length through cast Time Elapsed 16 ms List Count Time Elapsed 3 ms List Count() Time Elapsed 18 ms链接地址: http://www.djcxy.com/p/53924.html