Greg's Blog

helping me remember what I figure out

Optimising Looping Over Lists

| Comments

There is a always lot of talk about optimisation, shaving off those precious milliseconds, in some cases manifesting itself as an almost a obsessive compulsive behaviour. I am not saying to that optimisation is not important or indeed relevant. It definitely has it’s place, but I believe only, when things are going wrong, most commonly running slowly. So why did I decide to blog about optimising loops, well personally I wanted to document a little best practice, something to add to my tool set and use from the outset.

About a month ago, a question arose on the CF-talk list about looping over a list in cfscript, as in:

<cfset theList = “apples, oranges, pears” />

<cfloop index = “theIndex” list = “#theList#” delimiters = “,”>
<cfoutput>#theIndex#</cfoutput><br />
</cfloop>

One response suggested the following:

<cfset list=”apple,orange,pear” />

<cfscript>
for (i = 1; i lte listLen(list); i = i + 1) {
element = listGetAt(list, i);
writeOutput(element);
}
</cfscript>

Which works, however there are one or two things that you could optimise here. The first is irrelevant if you are using CFMX, but in older versions by setting your list within the cfscript tag you can save yourself a call to the CFML parser. Also this code snippet evaluates (as was pointed out) for each iteration of the loop how long the list is. Since in this case the length does not change this is completely unnecessary. So you can save yourself some processing by moving the length evaluation outside the loop. Hence we now have:

<cfscript>
list=”apple,orange,pear”;
theLength = listLen(list);
for (i = 1; i lte theLength; i = i + 1) {
writeOutput(listGetAt(list, i)&”<br />”);
}
</cfscript>

And now the final small optimisation trick. Barney pointed out that Array access is much faster than list access. So converting your list to an Array can again help shave off a few cycles, by avoiding a call to ListGetAt() and of course benefiting from the faster access to arrays.

<cfscript>
list=”apple,orange,pear”;
myArray = ListToArray(list);
theLength = arrayLen(myArray);
for (i = 1; i lte theLength; i = i + 1) {
writeOutput(myArray[i]&”<br />”);
}
</cfscript>

Now having said all this, consider the following: to really optimise your loops, consider if you really need to use them in the first place!