Why IIF() Should be Avoided

I was recently reviewing some code from one of my client projects and saw that the previous developer had liked to use IIF() functions to handle the conditional switching of things like button labels. I idly quipped on Twitter that Every time you execute IIF() an angel loses its wings. A few minutes later a request for some explanation came in on Facebook: Why's that? I like IIF(). Here is why you should avoid IIF().

Its Evaluate()

According to the Adobe ColdFusion 8 Documentation, IIF() is equivalent to the following code:

<cfif condition>
<cfset result = Evaluate(string_expression1)>
<cfelse>
<cfset result = Evaluate(string_expression2)>
</cfif>

What that means is that each time you execute IIF, its calling Evaluate(). I've read a few places, such as Ray Camden's Blog, that the performance of Evaluate isn't as bad as it used to be, but it still can't be good; dynamic execution of code costs processing power because it has to be computed at run-time.

Its Evaluate(), part 2

Under the hood, IIF() is executing an Evaluate() against at least one of your parameters. If you don't have to run Evaluate() to solve your problem, you don't need to call IIF() to do it either, and the places where you have to use Evaluate() are few. In fact, I'd bet that almost all uses of IIF() are to conditionally display strings, something like this:

<cfoutput>#IIF((Query.RecordCount gt 1), DE("Records"), DE("Record"))#</cfoutput>

See what you have to do there? You have to escape your strings just to use IIF(). If you wouldn't need Evaluate() to handle the logic of your code, then you don't need IIF().

Easy String Switching

If you're using IIF() to handle string switching like the example above because it's shorter to type, you're better of writing something like this utility function I wrote. Its going to save you some processing power, and it's actually shorter:

IIF((Query.RecordCount gt 1), DE("Records"), DE("Record"))
IfElse((Query.RecordCount gt 1), "Records", "Record")

Summary

  1. Using IIF() is probably slower than a regular if/else block because its using Evaluate().
  2. IIF() uses Evaluate() so you shouldn't use it unless you need to Evaluate().
  3. IIF() actually takes more typing than similar "inline" case solutions.

So, just remember: Every time you execute IIF() an angel loses its wings.

I also found quote from Sean Corfield about IIF() that makes it sound like IIF() actually Evaluate()s both the 2nd and 3rd argument both. I seriously hope he was mistaken or this quote is too old to be applicable.

 

Comments

JediHomer's Gravatar When I've used iif I remove the need for the DE sections, you can do something like...

iif(bTrueExpression, '"That would be true"', '"False unfortunately"');

If I just need a boolean back then this can work to

iif(bTrueExpression, true, false);
Eric Cobb's Gravatar It's #3 on Adobe's list of Coding Best Practices for ColdFusion Performance, (http://www.adobe.com/devnet/coldfusion/articles/co...), and avoiding Evaluate() is #4. :)
Jon Hartmann's Gravatar @jedihomer: If you're using the double quotes, you're right in that you avoid the need for the DE() functions, but you're not avoiding the fact that you're still running the strings through an Evaluate(). As for the case where you need a boolean... I'm not really sure where you'd ever need that in ColdFusion. If any statement expresses a true or false nature to satisfy the first parameter of IIF(), it should also satisfy the requirements for any other true/false value.

@Eric: Awesome! I was looking for a link to something like that, because I knew I'd read it somewhere, but I couldn't find it.
Carrie's Gravatar Thanks for the explanation, Jon!
Jon Hartmann's Gravatar @Carrie: No problem!
Seb Duggan's Gravatar Also, with the advent of ColdFusion 9, we can use the new ternary operator - which I believe is far more efficient than iif() ever was...

(On a related note, I was horrified today to see the following in some of my old code:

#Evaluate("Form.text" & i)#

Needless to say, I've updated it all...)
Hem Talreja's Gravatar You are correct, if possible we should aviod IIF().

CF9 does have a new ternary operator that is similar to the one used in Action Script (AS3)
( condition ? foo : bar ) example (Query.RecordCount gt 1 ? 'Records' : 'Record')

-Hem
Jon Hartmann's Gravatar @Seb + @Hem:

Thanks for pointing out the new ternary operator in CF9; I've not done extensive work with CF for a while and haven't had much exposure to CF9 post-beta. The syntax for the CF ternary - ( condition ? foo : bar) - that you cite is common to ActionScript, JavaScript, and C#, so its a rather standard form.

So... use it if you can, use a custom function if you can't, and never use IIF() :)
Comments are not allowed for this entry.
Jon Hartmann, July 2011

I'm Jon Hartmann and I'm a Javascript fanatic, UX/UI evangelist and former ColdFusion master. I blog about mysterious error messages, user interface design questions, and all things baffling and irksome about programming for the web.

Learn more about me on LinkedIn.