This is as summary of what I’ve learned about code efficiency in the past
couple of weeks. A lot of the things I didn’t even think about are actually
wrong, or at least not as efficient as they could be. The general idea is to
cut back on evaluation as much as possible.
Using structKeyExists() instead of isDefined()
Think about it, ALL coldfusion variables are in structures, right? So
instead of isDefined(’myvar’) where coldfusion doesn’t know what struct to start
in and therefore has to look through every scope to find the instance of myvar
and see if it exists, you are now telling coldfusion exactly where to look using
structKeyExists(’variables’, ‘myvar’). It’s the difference between someone
saying “turn to page 123 paragraph 2 on Insects” and “find the part about Insects”. Well, you can go to the index in the book and look at all of the places Insects are mentioned, or you can just go to the page because the information was given to you… much better!
Looping
Everyone has done it, the classic loop through a list. Here’s how it would
look:
<cfloop from="1" to="#listlen(mylist)#" index="i"> #i# </cfloop>
Ok, that’s decent code, and certainly what you will find out there as the
“standard” way of doing things, but this can be more efficient:
<cfset loopThrough=listlen(mylist)> <cfloop from="1" to="#loopThrough#" index="i"> #i# </cfloop>
Why? Instead of having to not only loop through your list x number of times,
the first example would also be evaluating #listlen(mylist)# x times as well…
twice the effort! It’s much less taxing on the system to define variables than
to re-evaluate over and over… even if it is less characters on the page.
If it’s boolean, don’t bother with the “eq 1″ or “neq NO” etc.
If you are going to have a boolean returned by a variable, don’t bother
setting what it’s equal to, you’re just wasting space, plus your code looks
cleaner. Examples:
<cfset isEfficient = 1> <cfif isEfficient>it's efficient!</cfif> <cfif isEfficient = '1'>It's NOT as efficient.</cfif>
The variable above, “isEfficient” could also be set to any of these boolean
combinations and it would still work:
- yes/no
- true/false
- 1 (OR ANY numeric value that is NOT 0… yes, that means ‘-.000001′ &
59990289 will both evaluate True) / 0
Eliminate “Else” from If statements where possible.
If you’re like me, this one seemed ridiculous, right? I know I thought I
only used “else” when necessary, but I was SO wrong. I have to admit though,
this is a method that is really used more on the presentation side than the
logic side, even though you can apply it to both. Let’s see an example.
This is a pretty classic example. Let’s say we have a bunch of table rows we
want to have with colors that fluxuate by row. First, we’ll look at the if/else
way:
<cfloop from="1" to="5" index="i"> <cfif NOT mod(i)> <td style="color: red"> </td> <cfelse> <td style="color: blue"> </td> </cfif> </cfloop>
Let’s see what we can do to Improve.
<!--add to css style--> .line0 {color: red} .line1 {color: blue} <cfloop from="1" to="5" index="i"> <td class="line#mod(i)#"> </td> </cfloop>
Much Better! But there is more to it than just this example. Let’s look at
a different example:
<cfset isWidgets = 1> <cfif isWidgets> <p>There are widgets!</p> <cfelse> <p>There aren't any widgets...</p> </cfif>
Ok, so this might not be the most efficient thing to do in every situation,
but as this is an example to build on, here’s how we could eliminate the
“else”:
<cfset isWidgets = 1> <cfset widgetText = "There aren't any Widgets..."> <cfif isWidgets> <cfset widgetText = "There are widgets!"> </cfif> <cfoutput><p>#widgetText#</p></cfoutput>
It’s important to note that doing this:
<cfset isWidgets = 1> <cfset widgetText = ""> <cfif isWidgets> <cfset widgetText = "There are widgets!"> <cfelse> <cfset widgetText = "There aren't any Widgets..."> </cfif> <cfoutput><p>#widgetText#</p></cfoutput>
Is even less efficient than the first example, because you not only still
have an else statement, but more variables and more characters floating about.
Therefore, we could also glean that starting off by defining a variable with one
of the options for its value is another way to reduce code and increase
efficiency… of course, that’s not possible in many situations, but where it is, it’s a good idea.
Use cfscript
I always shied away from this tag in the past. I was a self taught cf’er and
while I certainly love the simplicity of the tag based cf language, cfscript
isn’t as scary as I thought. You pretty much just strip the “cf” off of the
tags and add some “;”. Sure, there’s a little more to it, but really, you can
figure it out!