Ever since Microsoft introduced Language Integrated Query to the .NET framework (also known as LINQ) developers have been using it extensively to work with collections.
From a simple filter, to an aggregation, to a transformation, LINQ is the technology of choice to keep code clean and readable. We even have providers that convert LINQ instructions into SQL commands that will be run in some database.
In this article I’m going to compare the performance of ToList versus ToArray when creating short lived collections. I’m also going to execute the test in different versions of the framework (.NET Framework 4.8, .NET 7 and .NET 8) so we can also see how much the performance have improved over the years.
One of the coding guidelines for the applications I manage dictates the following:
Always use IReadOnlyCollection instead of IEnumerable when passing collections between application layers and ToArray should be used to force the enumeration.
Because we developers are curious by default and need to understand why things are implemented in a given way, every time we have a new team member, that coding guideline usually leads to the following conversation:
Q:Why do we use IReadOnlyCollection in POCOs instead of IEnumerable? A:Well, because we want the contracts to clearly state the collection is in memory, hence no multiple enumerations will occur, and any mapping problems will happen in the corresponding layer. Q:Fair enough, but why ToArray? That interface is implemented by arrays and lists, I could be using ToList and have the same result. A:The result is the same, that’s a fact, but ToArray is usually faster and more memory efficient than ToList, and since it’s a short lived collection that won’t be mutated, the former is preferred.
I’m going to use the well known C# library BenchmarkDotNet to run the tests and the environment will be the following:
The test consists in the creation of a collection that holds random integers, being the size defined by a parameter. To ensure the randomness does not affect the results, the values are cached into an array and before invoking either ToArray or ToList it is converted into a new IEnumerable, not just a cast that could lead to internal optimizations.
Because we want to decide, for a given application, between ToArray or ToList based on performance, let’s first analyze the results for each framework version.
In this article we compared the performance of ToArray versus ToList and concluded the former performs better most of the time by being faster and more memory efficient, so consider using it when creating short lived collections were enumeration must be forced.
We also concluded that .NET 8, the version still to be released, will bring fantastic performance upgrades in this regards. Not only it is significantly faster than the older versions, it also brings ToArray and ToList so close that it’s almost indifferent which method should be used.