Duncan's blog

October 18, 2012

ColdFusion cfloop versus cfscript for loop performance

Filed under: Coldfusion — duncan @ 7:01 pm
Tags: , ,

I’m sure most web developers are aware that, in Javascript, it’s generally considered best practice to do this:

for (var i = 0, len = array.length; i < len; i++) { }

instead of this:

for (var i = 0; i < array.length; i++) { }

The theory being that you improve performance by caching the array length once, instead of each time you iterate over the loop (although it’s open to debate how important this is; it really only benefits IE).

I decided to see if there was any benefit in doing the same thing with array loops in ColdFusion. Initially just tested with CFML, then again with CFScript, to see if there were any differences.

<!--- start with a blank file each time --->
<cfif fileExists("arraylen.txt")>
	<cffile action="delete" file="arraylen.txt">

<cfloop index="j" from="1" to="1000">
	<!--- create a large array to loop over later --->
	<cfset myArray = []>	
	<cfloop index="i" from="1" to="10000000"><cfset arrayAppend(myArray, "")></cfloop>

		// Method 1
		tick = GetTickCount();

		for (i=1; i <= arrayLen(myArray); i++) {}

			type	= "CFScript (arrayLen)",
			tick	= tick

		// Method 2
		tick = GetTickCount();

		len = arrayLen(myArray);

		for (i=1; i <= len; i++) {}

			type	= "CFScript (var'ed)",
			tick	= tick

	<!--- Method 1 --->
	<cfset tick = GetTickCount()>

	<cfloop index="i" from="1" to="#arrayLen(myArray)#"></cfloop>

	<cfset recordTime(
		type	= "CFML (arrayLen)",
		tick	= tick

	<!--- Method 2 --->
	<cfset tick = GetTickCount()>

	<cfset len = arrayLen(myArray)>

	<cfloop index="i" from="1" to="#len#"></cfloop>

	<cfset recordTime(
		type	= "CFML (var'ed)",
		tick	= tick

<cffunction name="recordTime" output="false" returntype="void">
	<cfargument name="type" type="string" required="true">
	<cfargument name="tick" type="numeric" required="true">

	<cfset var tock = GetTickCount()>
	<cfset var time = tock - arguments.tick>

	<cffile action="append" output="#arguments.type##chr(9)##time#ms" file="arraylen.txt">

What I did find was that the two methods, of either calculating arrayLen() within the FOR loop, or storing it as a variable, hardly differed at all in performance.

However there was a big difference in performance between CFML and CFScript. In this case, the looping was much slower in CFScript. This isn’t something new, I’m sure I’ve heard this before, but it was an interesting reminder for me that sometimes it’s not always best to write everything in CFScript.

So here’s the results showing the average times from running this 1000 times:

CFML (arrayLen) 257.883ms
CFML (var’ed) 258.284ms
CFScript (arrayLen) 1259.294ms
CFScript (var’ed) 1180.07ms

As we can see, the difference between caching the array length in a variable, or using arrayLen() for the loop limit, is negligible in CFML, less than 0.5 of a millisecond after 1000 iterations!

However in CFScript, it seems slightly quicker to use a variable instead of referring to arrayLen() within the iterator. But not so much that I’d say I’d favour one method over the other. Although I’ll certainly think twice before writing array loops in CFScript instead of CFML… although in reality the difference in performance is relatively minor (unless you’re working on massive arrays and/or have a high-traffic application).

PS: I’m running this on Adobe ColdFusion 9,0,1,274733 on Windows 7, YMMV 🙂


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: