Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a practical reason why LINQ's LongCount extension method was added?

LINQ has 2 methods for counting enumerables: Count and LongCount. Practically the only difference between these two is that the first returns an int, while the second returns a long.

I'm unclear as to why the second method was added. It seems its only use case would be to handle enumerables of over 2B elements. This seems like a poor decision to me, for a few reasons:

  1. Most BCL collections are backed by single-dimensional arrays, which have lengths that are guaranteed to fit in an int. Trying to go past that will raise an OverflowException / OutOfMemoryException.

  2. LongCount is O(n) since IEnumerable is lazy. If you have a 3B element enumerable, you call LongCount on it, and then you iterate through it again (which you will have to if you want to use any of the values), you will be adding an extra 3B iterations, which will be extremely slow, and hiding it from the developer.

  3. Other LINQ operations, such as ToArray / ToList, do not support enumerables with 2B+ elements because of (1).

Am I missing something here, or is there a more practical reason why LongCount was added? Thanks.

like image 650
James Ko Avatar asked Nov 11 '16 22:11

James Ko


1 Answers

I have no first-hand knowledge of this design decision but I can offer an educated guess.

The method is of obvious usefulness for IQueryable; the query could easily be backed by an enormous database table.

I would expect

IQueryable<Foo> q = whatever;
long result1 = q.LongCount();
long result2 = q.AsEnumerable().LongCount();

to produce the same answer. It seems perverse to require in-memory queries to use a different method that returns a different type, particularly when it is so easy to implement the enumerable version.

But like I said, that's an educated guess; hopefully someone who actually worked on this design might chime in.

like image 118
Eric Lippert Avatar answered Nov 05 '22 10:11

Eric Lippert