CFTIMER for CF6

Ever wanted CFTIMER support on CF6?  I hadn't either until this
evening when I needed to some some code and it wasn't going to work to
do my standard start = gettickcount() ... #gettickcount() - start# routine.  So I wrote my own, and thought I'd share.

Drop this in timer.cfm inside your $cfwebroot/WEB-INF/cftags directory:

<cfif NOT thistag.hasEndTag>
    <cfthrow type="MissingClosingTagException"
        message="You must provide an end tag for CFTIMER" />
</cfif>
<cfparam name="attributes.label" />
<cfif thistag.executionMode EQ "start">
    <cfif NOT structKeyExists(request, "__cftimer")>
        <cfset data = structNew() />
        <cfset data.stack = arrayNew(1) />
        <cfset data.results = arrayNew(1) />
        <cfset request["__cftimer"] = data />
    <cfelse>
        <cfset data = request["__cftimer"] />
    </cfif>
    <cfset s = structNew() />
    <cfset s.label = attributes.label />
    <cfset s.depth = arrayLen(data.stack) />
    <cfset arrayAppend(data.results, s) />
    <cfset arrayAppend(data.stack, gettickcount()) />
<cfelse>
    <cfset stoptime = gettickcount() />
    <cfset length = arrayLen(data.stack) />
    <cfset elapsed = stoptime - data.stack[length] />
    <cfset arrayDeleteAt(data.stack, length) />
    <cfset s.elapsed = elapsed />
</cfif>

Next add this block to your $cfwebroot/WEB-INF/debug/classic.cfm
file, around line 450 or so.  It really doesn't matter where, but
I wanted it just above the 'exceptions' block, so that's where I put it:

<!--- fake CFTIMER results --->
<cfif structKeyExists(request, "__cftimer")>
<cfoutput>
    <p class="cfdebug"><hr />
    <b class="cfdebuglge"><a name="cfdebug_cftimer">CFTIMER</a></b>
    </p>
    <table border="1" cellspacing="0" cellpadding="3">
    <tr>
        <th>Label</th>
        <th>Time</th>
    </tr>
    <cfset results = request["__cftimer"].results />
    <cfloop from="1" to="#arrayLen(results)#" index="i">
        <tr>
            <td style="padding-left: #results[i].depth + 1#em;">#results[i].label#</td>
            <td align="right">#results[i].elapsed# ms</td>
        </tr>
    </cfloop>
    </table>
</cfoutput>
</cfif>

That's it.  Just start using CFTIMER in your code, keeping in
mind that only the 'label' attribute is supported, and that it's
required.  I'm not sure about the real CFTIMER, but mine handles
nesting of CFTIMER tags in a graceful manner, indenting child tags like
the 'tree' execution times display does.  Nesting needn't been in
the same file, just any time a CFTIMER is enclosed in another,
regardless of template structure. 

As you can tell, the tag and debugging output make use of a request-scope variable named __cftimer
Hopefully that won't collide with any other variable names in any
applications, but if you get weird results, that might be what's
happening.

edit:
I should note that the tag and debugging output will work equally as
well installed in the custom tag directory of choice.  There's no
real reason to install the tag in the WEB-INF/cftags
directory other than a) for the tag insight in your editor to work
without having to set up a custom tag in it's dictionary and b) to
allow it to work server-wide without interfering with any existing
CF_TIMER tags that may be installed already.

Comments are closed.