Optimizing code by understanding usage
During code review, I ran into the following code (simplified):
We have some wrapper object for IEnumerable and allow to access it by index.
I don’t like this code, and suggested this version, instead:
The problem is that if you’ll look at the code of ElementAt(), it is already doing that, so why the duplicate work? It is specialized to make things fast for similar scenarios, why do I write the same code again?
Because I’m familiar with the usage scenario. A really common usage pattern for the wrapper object is something like this:
The difference between what ElementAt() does and what I do in the second version of the code is that my version will materialize the values. If you are calling that in a for loop, you’ll pay the cost of iterating over all the items once.
On the other hand, since the instance we pass to ElementAt() isn’t one that has an indexer, we’ll have to scan through the enumerator multiple times. A for loop with this implementation is a quadratic accident waiting to happen.