Hacker News new | ask | show | jobs
by enntwo 5879 days ago
One small caution when using LINQ, especially in performance critical areas (XNA for instance): .Count and .Count() are dramatically difference in performance, when simply looking for the size of an array or list, be sure to use the .Count property as it is orders of magnitude faster. If you are using LINQ else where, .Count() will achieve the same behavior but will be much slower, so it can be a tough optimization to track down.
2 comments

The .Count() method in LINQ to objects checks to see if the IEnumerable implements ICollection, and if so then just calls the .Count property.

Of course, calling the .Count property yourself is more efficient, but not by orders of magnitude.

Thank you for this, this was apparently fixed in .NET 4.0 which I was unaware of.

I think there is still some validity in my post in confusing whether you are using native accessing or routing through an additional tool/library, but the fix definitely elimates the performance hit I was discussing, so much of my post was in error.

edit: Also 3.5 it seems, I need to be more up-to-date with my concerns.

Everyone get's that wrong, including Microsoft's documentation ;). It's a good optimization though, in spite of the LSP violation.
Similarly, it is very easy and intuitive and horribly inefficient to write something like:

int countOfThings = DatabaseRepositoryType.GetThings().Count();

As it will go to the database, pull all of the matching rows locally, create all of the objects, and then iterate through them just increment a counter. Creating a .GetCount() method which calls down to a SQL "SELECT COUNT()" query is more work to write, but runs about a thousand times faster.

This is not quite correct.

The SQL generated in this case depends on the return type of GetThings(). If it returns an IEnumerable<> then it is indeed a terrible thing to do, but if it returns an IQueryable<> then the SQL will be a SELECT COUNT() query, and no objects will be created.

Care does have to be taken when writing this sort of code!