user2598794
user2598794

Reputation: 727

How is collection 'Length' property accessed in for loop

I know that in the following code array 'Length' property is not called on every loop iteration because Jit compiler is clever enough to recognize it as property (not method) and optimize the code to call it only once storing internally the value in the temporary variable:

Int32[] myArr = new Int32[100];
for(Int32 index = 0; index < myArr.Length; index++) {
// Do something with the current item
}

So there is no need for developer to trying to optimize this by caching the length to a local variable. My question: is it true for all collection types in .Net? For instance, suppose I have a List and call 'Count' property in for loop. Shouldn't I optimize this?

Upvotes: 3

Views: 584

Answers (1)

Eric Lippert
Eric Lippert

Reputation: 660159

I know that in the following code array 'Length' property is not called on every loop iteration because Jit compiler is clever enough to recognize it as property (not method)

Though Length is, from the perspective of the type system a property, from the perspective of the jitter it is a special instruction just for loading the length of an array. That's the thing that enables the jitter to perform this optimization.

I note also that there is a larger optimization which you failed to mention. Checking the length is cheap. The larger optimization here is that the jitter can elide checks on the index operation into the array because it knows that the loop variable will always be in the bounds of the array. Since those checks can throw exceptions, by eliding them the jitter makes it easier to analyze the control flow of the method, and can therefore potentially do even better optimizations to the rest of the method.

is it true for all collection types in .Net?

The jitter is permitted to make that optimization for other collection types if it can prove that doing so is correct. Whether it actually does so or not you can test using science; observe the code generated by the jitter and see if it has this optimization. My guess would be that the jitter does not have this optimization.

For instance, suppose I have a List and call 'Count' property in for loop. Shouldn't I optimize this?

Now we come to the real crux of the question. Absolutely you should not optimize this. Optimization is incredibly expensive; your employer pays you for every minute you're spending optimizing your code, so you should be optimizing the thing that produces the biggest user-observable win. Getting the count of a list takes nanoseconds. There is no program in the world whose success in the marketplace was determined by whether or not someone removed a couple nanoseconds from a loop that checked a list count unnecessarily.

The way to spend your time doing performance optimizations is first have a customer-focused goal. That's what lets you know when you can stop worrying about performance and spend your money on something more important. Second, measure progress against that goal every day. Third, if and ONLY if you are not meeting your goal, use a profiler to determine where the code is actually not sufficiently performant. Then optimize the heck out of that thing, and that thing alone.

Nano-optimizations are not the way to engineer performance. They just make the code harder to read and maintain. Use a good engineering discipline when analyzing performance, not a collection of tips and tricks.

Upvotes: 8

Related Questions