Question

On my test box I have ColdFusion 10 and have allocated just 1gig: "Maximum JVM Heap Size (in MB) = 1024".

I have a process that loops around 1000 times. Each loop iteration calls a custom tag ~200 times. So in all about 200,000 calls. The process never finishes, I eventually run out of memory. I'm sure it's what I'm doing inside the tags that is the problem and not the tags themselves. But I wanted to prove that. I ran this test and it seems that ColdFusion functions are much faster 2.7secs as opposed to 14.6secs. The test just increments a number.

My question is: Does this appear to be a valid test? If functions are so much faster should it be a rule of thumb to use them instead of custom tags whenever possible?

test results:

x = 0
Running good customtag 1000000 times...
x = 1000000
Time to complete: 14627

x = 0
Running good function 1000000 times...
x = 1000001
Time to complete: 2793

good.cfm custom tag:

<cfparam name="ATTRIBUTES.x" type="numeric" default="0">

<cfif thisTag.ExecutionMode eq "end">
    <cfset request.x = ATTRIBUTES.x+1>
    <cfset thistag.generatedcontent = "">
</cfif>

test code:

<cffunction name="good" output="false" returntype="Numeric" access="private">
    <cfargument name="numIn" type="numeric" required="true">
    <cfset var x = 0>
    <cfset x = arguments.numIn + 1>
    <cfreturn x>
</cffunction>

<cfset loopNum = 1000000>
<cfset request.x = 0>

<cfoutput>
    x = #request.x#<br>
    Running good customtag #loopNum# times...<br>
</cfoutput>
<cfset tBegin = GetTickCount()>
<cfloop from="1" to="#loopNum#" index="i">
    <cf_good x="#request.x#"></cf_good>
</cfloop>
<cfset tEnd = GetTickCount()>
<cfset scriptTime = (tEnd - tBegin)>
<cfoutput>
    x = #request.x#<br>
    Time to complete: #scriptTime#<br>
</cfoutput>

<cfset request.x = 0>
<cfoutput>
    x = #request.x#<br>
    Running good function #loopNum# times...<br>
</cfoutput>
<cfset tBegin = GetTickCount()>
<cfloop from="1" to="#loopNum#" index="i">
    <cfset request.x = good(i)>
</cfloop>
<cfset tEnd = GetTickCount()>
<cfset scriptTime = (tEnd - tBegin)>
<cfoutput>
    x = #request.x#<br>
    Time to complete: #scriptTime#<br>
</cfoutput>
Was it helpful?

Solution

You're comparing apples to oranges: custom tags and functions are not interchangeable concepts. Whilst they can both be coded to achieve much the same end, it would generally be a poor decision to use a custom tag where a function is appropriate; and equally a poor choice to use a function where a custom tag is a better fit.

Functions are for data manipulation; custom tags are for text / content manipulation. So your functions belong in your business logic, and your custom tags belong in your display logic.

Both have their place.

If you're looping over something 1000 times and calling some functionality 200 times per iteration... that really doesn't sound like you should be using a custom tag (it's not preparing text for output, is it?); it sounds like data-processing, so should be handled by functions (hopefully ones that are encapsulated in objects appropriately...)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top