Why IIF() Should be Avoided
- May 17, 2010 11:37 AM
- ColdFusion
- Comments (8)
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:
<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:
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:
IfElse((Query.RecordCount gt 1), "Records", "Record")
Summary
- Using IIF() is probably slower than a regular if/else block because its using Evaluate().
- IIF() uses Evaluate() so you shouldn't use it unless you need to Evaluate().
- IIF() actually takes more typing than similar "inline" case solutions.
So, just remember: Every time you execute IIF() an angel loses its wings.
Comments
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: 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.
(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...)
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
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() :)