Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching variables in a `for` loop

Tags:

c#

for-loop

I've been reading tips about Javascript performance boosting and one tip said to cache all the variables (that don't change) in the loops comparer statement and I was wondering if this also applied to .NET.

Assuming I had a simple for loop, which one of the following would be faster or would they be the same?

No Cache:

for (int i = 0; i < someArray.Length; i++)
{

}

With Cache:

for (int i = 0, count = someArray.Length; i < count; i++)
{

}

According to the article "caching" the value of Length cuts out one operation in the loop because its faster to access local variables compared to accessing members of an object. Is it actually faster declaring a local variable compared to simply accessing the member? Does the compiler pick up on this and automatically cache the value? Is there any negatives in declaring a local variable over accessing the member?

Whilst speed is probably a key factor here, its not the only one. My next question would probably be which one is more efficient. Which uses less memory allocations? Which performs less stack manipulation? etc...

From comments, it seems accessing array lengths is pretty fast. Lets say I use an IList<> instead. Would caching the value of Count be faster than retrieving it each iteration?

like image 785
jduncanator Avatar asked May 19 '13 07:05

jduncanator


2 Answers

Just to provide a different answer. Caching the length value may help you in some particular cases.

In my case, we were using a sample code with selenium for ui tests. The code looked like this:

for (int i = 0; i < Grid.VisibleRows.Length; i++) {
    // do something
}

Our grid was just a class representing an html table. The VisibleRows was getting a IWebElement[] and then using Length property. Each iteration implied to go the UI and get all rows.

Of course another implementation might be to just go to the UI once and get the length (instead of counting the rows in memory), but still moving the code out of the for loop implied an improvement on performance - I reduced the number of roundtrips to the UI from many to just one.

So code now looks like this:

var rowsLength = Grid.VisibleRows.Length;
 for (int i = 0; i < rowsLength ; i++) {
        // do something
    }

For us, the manual caching worked out. Using a stopwatch we checked that we were able to reduce the time of that part of code from 32993 ms to 12020 MS

like image 163
Gonzalo.- Avatar answered Nov 06 '22 16:11

Gonzalo.-


I once tried caching vs. array.Length. Array.Length was faster. I think, thats because of inner structure of virtual machine and "safety". Whe you use .Length notation, it consider, that it will never overflow array. With variable, it is unknown and it makes additional tests. Assembly code looks one way, but inner behavior of virtual machine is other thing.

But on the other hand, you are doing premature optimalization.

like image 37
Martin Perry Avatar answered Nov 06 '22 15:11

Martin Perry