Archive for the ‘Uncategorized’ Category

Looping over Arrays

Wednesday, August 25th, 2010

I’ve been working in CF 7 a lot lately.  This has forced me to look at writing Coldfusion differently from what I’m used to, being Coldfusion 8 & 9.  An example is that in CF 7 there is no attribute available in the <cfloop> tag.  This means that I have to loop over an array by looping from 1 to however long the array is.  There are two ways to loop over an array in CF 7.  First is to evaluate the array length with each loop, and the second is to set the length of the loop into a variable and loop from 1 to that value.

To illustrate the first example of evaluating with each loop the code would look like:

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

</cfloop>

and the to illustrate the second example of setting the length first the code would look like:

<!-- set the length of the array -->
<cfset variables.aryLen = arrayLen(variables.myArray) />

<cfloop from="1" to="#variables.aryLen#" index="variables.i">

</cfloop>

Lastly, in Coldfusion 8 & 9 you can write it like the following:

<cfloop array="#variables.myArray#" index="variables.i">

</cfloop>

So of the first two options, clearly setting the length of the array into a variable has design advantages and should always be the preferred method. Nonetheless I was curious if there was really a performance difference.

I used the following script to loop over an array with 100,000 values using the three above methods.

<cfif NOT structKeyExists(SESSION, "asAttribute")>
	<cfset SESSION.asAttribute = arrayNew(1) />
</cfif>

<cfif NOT structKeyExists(SESSION, "setLength")>
	<cfset SESSION.setLength = arrayNew(1) />
</cfif>

<cfif NOT structKeyExists(SESSION, "evaluateLength")>
	<cfset SESSION.evaluateLength = arrayNew(1) />
</cfif>

<cfif NOT structKeyExists(SESSION, "refreshes")>
	<cfset SESSION.refreshes = 0 />
</cfif>

<cfset SESSION.refreshes = SESSION.refreshes + 1 />

<cfoutput>
	Number of refreshes: #SESSION.refreshes#<br /><br />
</cfoutput>

<!-- create an array -->
<cfset variables.myArray = arrayNew(1) />

<!-- populate array -->
<cfloop from="1" to="100000" index="variables.i">
	<cfset variables.myArray[variables.i] = "Value#variables.i#" />
</cfloop>

<cfset variables.startCount = getTickCount() />

<cfloop array="#variables.myArray#" index="variables.i">

</cfloop>

<cfset variables.endCount = getTickCount() />

<cfset variables.processingTime = variables.endCount - variables.startCount />

<cfset arrayAppend(SESSION.asAttribute, variables.processingTime) />

<cfset variables.attributeAvg = arrayAvg(SESSION.asAttribute) />

<cfoutput>
	Using as an attribute - <br />
	Average: #variables.attributeAvg#
</cfoutput>

<br /><br /><br />

<!-- set the length of the array -->
<cfset variables.aryLen = arrayLen(variables.myArray) />

<cfset variables.startCount = getTickCount() />

<cfloop from="1" to="#variables.aryLen#" index="variables.i">

</cfloop>

<cfset variables.endCount = getTickCount() />

<cfset variables.processingTime = variables.endCount - variables.startCount />

<cfset arrayAppend(SESSION.setLength, variables.processingTime) />

<cfset variables.attributeAvg = arrayAvg(SESSION.setLength) />

<cfoutput>
	Setting length in a varible - <br />
	Average: #variables.attributeAvg#
</cfoutput>

<br /><br /><br />

<cfset variables.startCount = getTickCount() />

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

</cfloop>

<cfset variables.endCount = getTickCount() />

<cfset variables.processingTime = variables.endCount - variables.startCount />

<cfset arrayAppend(SESSION.evaluateLength, variables.processingTime) />

<cfset variables.attributeAvg = arrayAvg(SESSION.evaluateLength) />

<cfoutput>
	Evaluating length for each loop - <br />
	Average: #variables.attributeAvg#
</cfoutput>

Each was timed and stored in the session. At the end of 10, 25, 50, and 100 page refreshes the average execution speed was determined for each method.

After all was said and done evaluating the array for each loop vs. setting the length and looping to the length was within 4 milliseconds running a loop over an array with 100,000 values. The following chart illustrates the differences.

Array Looping Execution Comparison

Hopefully, what is obvious from this is not so much that there is little to no difference in the execution time between pre-setting the array length vs. evaluating it with each loop, but that using the array as an attribute (which can only be used in Coldfusion 8 & 9) of the tag runs much faster than either of the other two methods. About 25 milliseconds faster.

Setting print margins using Eclipse to maintain line character length

Friday, May 14th, 2010

Sometimes you may have standard line lengths with which to work when writing code. If this is the case and your using Coldfusion and Eclipse with the cfEclipse plugin you can maintain the character length consistency by setting up the print margins to n character length.

Point being that when running the cfeclipse plugin you need to choose CFEclipse > Editor in the preferences left navigation. In the options you will check ‘Show print margin’, set the ‘Print margin column’ text field to the desired character length, and if you choose the ‘Print margin’ option in the ‘Appearance color options’ select box. Then choose the color you wish the margin to be. This will set a line length that will show in the code editor pane. Of course it will not wrap the line. It is still your duty as a developer to wrap appropriately. Nonetheless it does give you a guide for where the line should wrap at least.

If you’re writing Java then you would select General > Editor > Text Editors in the preferences pane.  Although the display is slightly different, generally follow the same steps as above for showing the print margin.

If you’re using Coldfusion Builder you will follow the same exact directions as listed just above for showing the print margins writing Java.

Lastly, if you’re using Flex Builder 3 you will again follow the same directions as above for showing print margins writing Java.