Adobe Solution Partner

February 9, 2007

The REAL reason you need to var-scope your local CFC function variables

Filed under: ColdFusion — Tags: — Tyson Vanek @ 9:17 am

So, Nat makes a great point that vars not specifically placed in the var scope become CFC instance variables. To be honest, I didn’t even realize this myself until he pointed it out. However, the REAL reason you should be explicitly var-scoping your local variables in a CFC method has to do with performance.

Attached to this post, you’ll find a small test application (varScopeTestApp.zip). The ColdFusion logic within the test application is quite simple – loop a specified number of times and set a simple variable equal to the current value of the loop counter. The test application compares 6 different methods of executing the exact same ColdFusion logic, and then displays the results. All you need to do to run the application is extract all of the contained files into a single directory on your application server, and then call the index.cfm page in your web browser. You can use the intLoopCount URL parameter in order to increase the size of the loop and really emphasize the performance difference. I would recommend a number around 500000.

The test application attempts to execute this same code concept using 6 different ColdFusion approaches.

  • As inline ColdFusion code written with CF tags
  • As inline ColdFusion code written within a CFSCRIPT block
  • As a call to a CFC function written with CF tags without explicitly var-scoped variables
  • As a call to a CFC function written within a CFSCRIPT block without explicitly var-scoped variables
  • As a call to a CFC function written with CF tags with explicitly var-scoped variables
  • As a call to a CFC function written within a CFSCRIPT block with explicitly var-scoped variables

In order to ensure that the execution time of each method is measured without being affected by concurrent thread resource contention, you’ll find that each of the 6 test cases executes within a named exclusive lock. This provides for the most accurate measure of the true performance of the code being executed.

You’ll make some interesting discoveries upon firing up this test application and seeing the results for yourself. Most notable, in my opinion, is the performance bulk added when the code is executed from within a CFC function without proper local var scoping. Going one step further, it would also seem that more bulk is added to the CFSCRIPT function than to the CF tag function. In my own tests, I found the CFSCRIPT function without var-scoped variables to be about 30% slower than the CF tag counterpart. And both CFC functions without explicitly var-scoped variables end up being roughly 2-3 times slower than the inline code.

Sure, we all despise the var keyword and the way that it has been implemented. And yes, we all agree that Adobe should introduce a new argument for the CFFUNCTION tag that would allow us to control the behavior of unscoped variables set within a CFC function. But until that magical revision arrives, we’ll just need to bite the bullet and give into the var keyword for the sake of general application performance.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Technorati
  • TwitThis

17 Comments »

  1. By the way, I should also point out that the performance gaps continue to increase for each variable within the loop. If you modify the supplied test application to set 2 or 3 or 4 local variables, the performance difference becomes even more evident.

    Comment by Tyson Vanek — February 9, 2007 @ 12:00 am

  2. Sigh.

    Comment by Steve Nelson — February 9, 2007 @ 12:00 am

  3. This is crazy. On top of potentially corrupting data when using application scoped CFCs, performance is killed when not using it.

    btw, i started upgrading Michael’s "VarScoper" tool to handle EVERY potential CF7 tag along with handle included files inside of a cfc.

    Suddenly this tool is going to become required for every CF developer. LAME!

    Comment by Steve Nelson — February 9, 2007 @ 12:00 am

  4. Sorry. When I first posted this, I had the wrong CFC in the zip file. The test application has been updated with the proper CFC. :)

    Comment by Tyson Vanek — February 9, 2007 @ 12:00 am

  5. Awesome. Now I get to write one more blog entry (when I get a chance) that’ll be titled, "Those aren’t the REAL reasons. THIS is the real reason you need to var-scope local variables"

    Comment by Nat Papovich — February 9, 2007 @ 12:00 am

  6. I am kind of at a loss to understand WebApper’s severe aversion to declaring variables. Just because scripting languages sometimes let us be a bit lazy doesn’t make it good practice. I don’t think it is crazy to use var, myself. When I declare things explicitly in a scope, I know where they some from and what value they start life with.

    I guess count me out of the ‘we’ that despise the var keyword.

    Comment by Chip Temm — February 9, 2007 @ 12:00 am

  7. Hey Chip! We’re definitely not averse to proper scoping. I’m of a personal habit to always scope every variable reference no matter if in .cfms or .cfcs and always use the var keyword except for plain ole "variables" scope in .cfms.

    What we are averse to is boneheaded language vocabulary decisions which are neither consistent nor well thought-out. The var keyword was not consistent with many many years of CFML language additions. What would have been consistent is a new scope called "local", which when applied inside a method body, acquires the same attributes of var-keyworded variables.

    The big problem is that there are serious consequences to not properly and consistently using the var keyword in your variable declarations. As Tyson has shown, and as I will show in a future post, you can get in deep trouble if you don’t always use it. And there are many (tens of? hundreds of?) thousands of examples of improperly var’ed variables in production code. Steve mentioned the "VarScoper" tool, which will correct those oversights in your source code.

    Comment by Nat Papovich — February 9, 2007 @ 12:00 am

  8. Precisely. Well put, Nat. I think all we’re saying, Chip, is that they should have implemented it as:

    <cfset var.myLocalVar = "foo">

    or, as Nat has suggested

    <cfset local.myLocalVar = "foo">

    Nobody here is saying we’re averse to declaring or scoping variables. I guess we’re just griping about the unusual way that it was implemented based on the existing syntax of the language.

    Comment by Tyson Vanek — February 9, 2007 @ 12:00 am

  9. One more thing I’d like to point out.

    Part of the specific reason I worked on the test application that accompanies this post was to establish a proof of concept for a client. A couple of the ColdFusion developers at this client sort of brushed me off a little when I mentioned that the vars in their application code should be properly declared and scoped. One of their arguments to me was that ColdFusion’s natural scope precedence will quite often eventually find the var in whatever scope it exists – which is, to some extent, true.

    However, I wanted to demonstrate to these developers why that approach simply wasn’t good enough. Aside from the cross-scope tangles they were susceptible to, I also knew that the cost of searching for these unscoped/undeclared variables would add up in the performance category. And since the client called us in to assist them with general performance problems, it was a bit frustrating when they didn’t want to take the advice I was giving them. But, when I showed them this test application harness, they could actually look at solid proof supporting my recommendation to adopt the best practice of always scoping and declaring their variables.

    Comment by Tyson Vanek — February 9, 2007 @ 12:00 am

  10. so if this is not the correct url to get the zip – to get the udf needed to run the app – there where is it??

    http://www.coldfusionmaster.com/varScopeTestApp.zip

    Comment by Kevin penny — March 8, 2007 @ 12:00 am

  11. Kevin,

    That is the correct URL for downloading the test application. The .ZIP was updated at that location with the proper CFC (test.cfc) used by the application. You can download the same file by clicking on the "Download" link supplied in the line of links following the original post. Either way, you should end up with the test application. If not, please let me know.

    Comment by Tyson Vanek — March 8, 2007 @ 12:00 am

  12. Ok – after looking at it a bit, I just removed the call to the ‘application.cfc.cfcUDF = createObject("component", "udf");’ in the application.cfm –

    (and again later to set that to the app scope – )

    Worked great after that – thanks!

    Comment by Kevin penny — March 8, 2007 @ 12:00 am

  13. Kevin,

    You’re absolutely right. There’s an orphaned reference to another CFC I had been using in a slightly modified version of this test application. I have corrected the files in the .ZIP so this won’t be an issue for other users.

    Thanks for pointing it out. :)

    Comment by Tyson Vanek — March 15, 2007 @ 12:00 am

  14. Hi from Madrid,

    I downloaded the test. For linux, I had to rename
    application.cfm to Application.cfm.

    I had to put
    <cfsetting enablecfoutputonly="yes" />
    in the Application.cfm so that those *terrible cfc-white- spaces* didn’t spoil the test.

    in all tests:
    cfscript is faster inline and in var-scoped-cfc.
    cftags are faster on unscoped-cfc

    Comment by hector — May 13, 2007 @ 12:00 am

  15. Downloaded the test. It’s working very good. Thx you, Mr Vanek.

    http://myflowerz.info:

    Comment by Andrew — October 6, 2007 @ 12:00 am

  16. I tried the test suite out and found as others have that using var was definitely the fastest. However I was curious what performance was like for the ‘var local = StructNew()’ and ‘use the ARGUMENTS scope as a local scope’ ideas (see http://www.webapper.net/index.cfm/2007/2/5/The-VAR-keyword-is-idiotic). I enhanced the test app with scenarios for those, and found that they were quite a bit slower than using var, though still a smidge faster than using nothing. I’ll be choosing to use var then, as it’s no worse a discipline to develop than scoping everything.

    Comment by Darren Cook — October 17, 2007 @ 12:00 am

  17. Just now examined the thread. Amazing job.

    Comment by Invoizona — June 12, 2011 @ 2:20 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

 

Server Down?

Maximize Web application uptime by drawing upon Webapper's years of experience tuning and stabilizing many of the world's largest ColdFusion Web applications. Contact us today!