Testing ColdFusion Custom Tag Processing Overhead

Posted November 29, 2007 at 11:36 AM

Tags: ColdFusion

The other day, when blogging about my final thoughts on Data Type vs. Data Value validation, my idea for a ColdFusion custom CFParam tag got a little traction. One of the thoughts exchanged was about the overhead that would come with the use of a ColdFusion custom tag. I am not too familiar with what overhead would be incurred, so I thought I would do a little speed testing.

The idea with this CFParam ColdFusion custom tag is that internally, we are wrapping the CFParam tag in a CFTry / CFCatch block to catch any failed type validation. Then, in the CFCatch block, we are setting the target variable equal to the default value of the failed tag:

 Launch code in new window » Download code as text file »

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!---
  • Try to Param the variable. For this experiment,
  • we are going to assume that these ATTRIBUTES
  • always defined.
  • --->
  • <cftry>
  • <cfparam
  • name="CALLER.#ATTRIBUTES.Name#"
  • type="#ATTRIBUTES.Type#"
  • default="#ATTRIBUTES.Default#"
  • />
  •  
  • <!--- Catch paraming errors. --->
  • <cfcatch>
  •  
  • <!---
  • Just set the variable to the given default
  • value that was passed in.
  • --->
  • <cfset "CALLER.#ATTRIBUTES.Name#" = ATTRIBUTES.Default />
  •  
  • </cfcatch>
  • </cftry>
  •  
  •  
  • <!--- Exit tag. --->
  • <cfexit method="exittag" />
  •  
  • </cfsilent>

This ColdFusion custom tag (param.cfm) does no attribute validation or anything like that. I am trying to keep it as simple as possible to really just test the overhead of the custom tag usage, not the validation logic.

When testing the overhead, I wanted to run two different scenarios: worst case and best case. In the worst case, all of the CFParam tags will fail and throw exceptions. In the best case, none of the tags will fail or throw exceptions.

Worst Case Scenario

In the worst case scenario, we are making sure that every paramed variable will fail its type validation. In the first CFTimer, we are using our ColdFusion custom tag and in the second CFTimer, we are using inline error handling:

 Launch code in new window » Download code as text file »

  • <!---
  • Set the number of variables we are going to be paraming
  • in our speed tests.
  • --->
  • <cfset intCount = 500 />
  •  
  •  
  • <!---
  • For our first run, we are going to use a ColdFusion custom
  • tag to param a variable. If the internal CFParam tag fails,
  • then the custom tag will take care of setting the default.
  • We are doing this to see what kind of overhead the custom
  • cfparaming tag adds to processing.
  • --->
  • <cftimer
  • type="outline"
  • label="ColdFusion Custom Tag">
  •  
  • <!--- Loop over a number of variables to param. --->
  • <cfloop
  • index="intI"
  • from="1"
  • to="#intCount#"
  • step="1">
  •  
  • <!---
  • Set a variable value that we know will fail the
  • following CFParam tag.
  • --->
  • <cfset FORM[ "varA#intI#" ] = "" />
  •  
  •  
  • <!--- Param the value using ColdFusion custom tag. --->
  • <cf_param
  • name="FORM.varA#intI#"
  • type="numeric"
  • default="0"
  • />
  •  
  •  
  • #FORM[ "varA#intI#" ]#
  •  
  • </cfloop>
  •  
  • </cftimer>
  •  
  •  
  • <!---
  • Now, we are going to param a bunch of variables in exactly
  • the same way that the first timer did; only, this time, we
  • are going to do the try / catch inline so that no custom
  • tag is needed.
  • --->
  • <cftimer
  • type="outline"
  • label="Inline CFTry / CFCatch">
  •  
  • <!--- Loop over a number of variables to param. --->
  • <cfloop
  • index="intI"
  • from="1"
  • to="#intCount#"
  • step="1">
  •  
  • <!---
  • Set a variable value that we know will fail the
  • following CFParam tag.
  • --->
  • <cfset FORM[ "varB#intI#" ] = "" />
  •  
  •  
  • <!--- Param the value using CFTry / CFCatch. --->
  • <cftry>
  • <cfparam
  • name="FORM.varB#intI#"
  • type="numeric"
  • default="1"
  • />
  •  
  • <!---
  • Catch the paraming value and then set the
  • variable to be the same as the default.
  • --->
  • <cfcatch>
  • <cfset FORM[ "varB#intI#" ] = 1 />
  • </cfcatch>
  • </cftry>
  •  
  •  
  • #FORM[ "varB#intI#" ]#
  •  
  • </cfloop>
  •  
  • </cftimer>

Running this code 5 times, I get the following times:

CF_Param ColdFusion Custom Tag

9,438 ms
1,0328 ms
9,672 ms
9,406 ms
9,375 ms

Average: 9,643 ms

Inline Error Handling

8,671 ms
8,875 ms
9,281 ms
8,687 ms
9,015 ms

Average: 8,905 ms

So, it looks like in the worst case scenario in which exceptions are always being thrown, there is definitely some overhead to the ColdFusion custom tag, but I would say not crazy, or rather, not too much overhead considering the high number of exceptions.

Best Case Scenario

Now, let's look at the best case scenario in which we never thrown an exception. Remember, we only expect CFParam exceptions to be generated when someone has messed with the XHTML or the URL. For 99% of our users, who are good people, we don't expect to have to handle exceptions. As such, the best case scenario will demonstrate more of what the average user will experience:

 Launch code in new window » Download code as text file »

  • <!---
  • Set the number of variables we are going to be paraming
  • in our speed tests.
  • --->
  • <cfset intCount = 500 />
  •  
  •  
  • <!---
  • For our first run, we are going to use a ColdFusion custom
  • tag to param a variable. If the internal CFParam tag fails,
  • then the custom tag will take care of setting the default.
  • We are doing this to see what kind of overhead the custom
  • cfparaming tag adds to processing.
  • --->
  • <cftimer
  • type="outline"
  • label="Non-Failing ColdFusion Custom Tag">
  •  
  • <!--- Loop over a number of variables to param. --->
  • <cfloop
  • index="intI"
  • from="1"
  • to="#intCount#"
  • step="1">
  •  
  • <!--- Set a variable value that we NOT fail. --->
  • <cfset FORM[ "varC#intI#" ] = 0 />
  •  
  •  
  • <!--- Param the value using ColdFusion custom tag. --->
  • <cf_param
  • name="FORM.varC#intI#"
  • type="numeric"
  • default="0"
  • />
  •  
  •  
  • #FORM[ "varC#intI#" ]#
  •  
  • </cfloop>
  •  
  • </cftimer>
  •  
  •  
  • <!---
  • Now, we are going to param a bunch of variables in exactly
  • the same way that the first timer did; only, this time, we
  • are going to do the try / catch inline so that no custom
  • tag is needed.
  • --->
  • <cftimer
  • type="outline"
  • label="Non-Failing Inline CFTry / CFCatch">
  •  
  • <!--- Loop over a number of variables to param. --->
  • <cfloop
  • index="intI"
  • from="1"
  • to="#intCount#"
  • step="1">
  •  
  • <!--- Set a variable value that we NOT fail. --->
  • <cfset FORM[ "varD#intI#" ] = 1 />
  •  
  •  
  • <!--- Param the value using CFTry / CFCatch. --->
  • <cftry>
  • <cfparam
  • name="FORM.varD#intI#"
  • type="numeric"
  • default="1"
  • />
  •  
  • <!---
  • Catch the paraming value and then set the
  • variable to be the same as the default.
  • --->
  • <cfcatch>
  • <cfset FORM[ "varD#intI#" ] = 1 />
  • </cfcatch>
  • </cftry>
  •  
  •  
  • #FORM[ "varD#intI#" ]#
  •  
  • </cfloop>
  •  
  • </cftimer>

Running this code 5 times, I get the following times:

CF_Param ColdFusion Custom Tag

735 ms
735 ms
734 ms
735 ms
812 ms

Average: 750 ms

Inline Error Handling

31 ms
15 ms
16 ms
31 ms
16 ms

Average: 21 ms

As you can see here, when we run into a best case scenario, the difference in performance between the CFParam tag and our ColdFusion custom tag is much more noticeable. Of course, this is for 500 CFParam executions, which is much greater than any normal page should ever have. With 1,2,3 or even 10 CFParam tags, the execution time will not be noticeable. However, on larger systems, this might not be a risk worth taking? Depends on how much optimization you want vs. readability / maintainability.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page




Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Nov 29, 2007 at 12:55 PM // reply »
12 Comments

That stinks. So you end up with a greater performance hit when the variable is valid. I thought it would be the opposite. In my applications, an invalid value is the exception, not the rule.


Nov 29, 2007 at 1:02 PM // reply »
7,572 Comments

@Brad,

Yeah, I am not sure how I feel about this. On one hand, there are so few variables on a page that need to be paramed (I think 30 was my biggest page EVER). But on the other hand, not sure how this scales. It might get slower and slower with large applications and concurrent requests. That is where my speed tests don't give data.

Also, this is slightly faster in ColdFusion 8, but barely.


Nov 29, 2007 at 1:12 PM // reply »
5 Comments

Just out of curiosity, is this code being used in the model, controller, or view of an app?


Nov 29, 2007 at 1:15 PM // reply »
7,572 Comments

@Andrew,

Is is the Controller. When the FORM is submitted back to page, the controller will take the form data and set it into the model and then pass it off to the service layer (at least, that is how I have it in my experiments).


Jul 11, 2008 at 4:24 AM // reply »
1 Comments

Hi Ben NADEL , I've seen you use this for years in many of your applications. While I understand it helps modulize I never understood the advantage over using includes. It always seemed to me to be a larger amount of overhead with no real benefit. Maybe you could explain why you would use this over simple includes?


Jul 11, 2008 at 8:08 AM // reply »
7,572 Comments

@John,

Custom tags creates encapsulated code to which you can pass arguments. While some of this same effect can be created using includes, they are fundamentally different gestures. ALso, there are things like looping and generated content catching that you simply cannot due with includes.


Post Comment  |  Ask Ben

Recent Blog Comments
Mar 22, 2010 at 7:43 AM
Terms Of Service / Privacy Policy Document Generator
Thankyou for this very helpful form. You've made my life much easier today. I'll have a look around your site... I'm sure there's some more good stuff here..Thanks Dave ... read »
Mar 22, 2010 at 7:21 AM
Encountered "(. Incorrect Select Statement, Expecting a 'FROM', But Encountered '(' Instead, A Select Statement Should Have a 'FROM' Construct.
I got this exception now. In case you're using var-es local struct, CF gives you couple of "new" exceptions: Encountered "local. and Encountered "id. Incorrect Select List, Incorrect select colum ... read »
Mar 22, 2010 at 3:08 AM
Ask Ben: Selecting XML Attributes Given Other XML Attributes
Thanks for the response. I finally discovered that I was getting this error because I had cfsetting enablecfoutputonly="yes" in Application.cfc, and was neither setting it to false elsewhere nor brac ... read »
Mar 21, 2010 at 8:57 PM
The Bourne Ultimatum Starring Matt Damon And Julia Stiles
late to the party, but my observation is this: rewatch carefully for the platonic nature of the relationship between nicki and jason. she never flirts with him. he never comes on to her. they alway ... read »
Mar 21, 2010 at 7:40 PM
Is Simulating User-Input Events With jQuery Ever A Good Idea?
A couple of things. One you embed the initial state of of more-info in the CSS. IMHO, that behavior should be in jQuery: moreInfo.hide(); It shows that the behavior your toggling and closing is mor ... read »
Mar 21, 2010 at 3:59 PM
Exploring ColdFusion Component Runtime Class Properties And Serialization
@Elliott, according to Ben's experiment, serializeJSON() doesn't access the private data by default - it doesn't even access the getHair() method - so trying to clone a Girl.cfc via serializeJSON/des ... read »
Mar 21, 2010 at 3:49 PM
Ask Ben: Javascript String Replace Method
I'm confused a bit by what you are asking, but if had this sentence: The color, red, is in the style statement; style: red;. and wanted to remove all or change all of the commas, colons, and semi-c ... read »
Mar 21, 2010 at 3:13 PM
Ask Ben: Javascript String Replace Method
I am trying to make a java program to count the number of times that these punctuation marks occur in a body of text: , : ; . ! - ' " ? / \ I am using this piece to ferret out the commas: numcommas ... read »