Thursday, December 24, 2009

CF9: One Difference Between the New Ternary Operator and IIF()

When I first saw the ternary operator in java, I confess I did not like it. To my way of thinking, it was odd and cryptic, and I did not see the advantage over a standard if/else statement. Well, I have come a long way. For simple comparisons I now prefer its sleeker syntax over the more bulky if/else construct.


So it was quite pleasing to see the ternary introduced in ColdFusion 9. I never much cared for the IIF() function. (Too reminiscent of MS Access I suppose) But stylistic preferences aside, I just noticed the behavior of the ternary operator differs from IIF() in another sense. It uses delayed evaluation.

Take this silly example. When someCondition is true, only the variable foo is defined.

   <cfset someCondition = true />
<cfif someCondition>
<cfset foo = 123>
<cfelse>
<cfset foo = 321>
<cfset bar = 88>
</cfif>


If you are using the new ternary operator, a statement like the one below would succeed. It does not matter that the variable bar is not defined. Because the second variable is only evaluated when someCondition is false.
 
<cfset result = someCondition ? foo : bar />

However, using IIF(), both variables are evaluated immediately, whether they are used or not. So this code would result in an error: "variable BAR is undefined"

 
<cfset result = IIF(someCondition, foo, bar) />
To avoid the error you would need to use the DE() function, which just feels awkward to me.

<cfset result = IIF(someCondition, foo, DE("bar")) />

So in this sense at least, the ternary operator is a bit smarter than the old IIF() function.

5 comments:

Travis January 5, 2010 at 10:31 AM  

I'm not running CF9 (yet, later this month probably) so I can't test this but have you tested the efficiency of this? IIF is highly discouraged (and has been for as long as I can remember) because of it's overhead. I'm curious to see a test of 10000 IIF and ternary syntax to see what is more efficient.

cfSearching January 5, 2010 at 12:11 PM  

@Travis,

No, I never ran any performance tests because I do not like IIF and never use it (Was my hint about its shortcomings too subtle ? ;)

But out of curiosity I ran some highly unofficial tests comparing the three options over 20k iterations. Predictably, IIF was the slowest (on average). Though not by a wide margin.

Ternary
(Overall: 547 ms) (Avg: 2.735 )

CFIF
(Overall: 766 ms) (Avg: 3.83 )

Ternary
(Overall: 875 ms) (Avg: 4.375 )

-Leigh

cfSearching January 5, 2010 at 12:15 PM  

Obviously the last stat should be labeled IIF, not Ternary.

Travis January 7, 2010 at 5:28 AM  

That's interesting. According to these results, the improvement of Ternary over CFIF is twice the improvement of CFIF over IIF. If this is correct, soon CFIF will get a bad rap too when doing simple operations like this. Do I see a new best practice on the horizon?

cfSearching January 8, 2010 at 9:32 AM  

@Travis,

Well those are highly unofficial numbers. The was some variance in the results. But yes, the overall trend was that ternary seemed the best of the bunch. I do not know if the average differences are enough to tarnish CFIF's reputation though. It is still far better than IIF (The "D" student of the class ;)

-Leigh

  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep