Calendar
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Recent Entries
Come On In, Rails-The Water's Warm
Shan's Simple Examples: File uploads with Flex and ColdFusion
Recent Comments
Google Calendar API - Creating a new Calendar with ColdFusion
Steve Julian said: When and where are you going to post the finished CFC's ? Thanks
[more]
Three Phases of Programmer Development
Pat Branley said: I normally think of those phase 2 people as 'programmers' and the phase 3 people as 'developers'.
I...
[more]
New Job Title: Front End Engineer
Sean Corfield said: Well, there's always the excellent Fusion Authority Quarterly Journal...
[more]
Down To The Wire: HTTP Sniffers
Brian M said: I second the mention of the Charles Web Debugging Proxy that Tariq mentioned. It is fantastic. It s...
[more]
New Job Title: Front End Engineer
Patrick said: Heya Sean. Good point. I never understood how they did things over there at SysCon, and I understand...
[more]
Archives By Subject
Business of Software (4) [RSS]
ColdFusion (318) [RSS]
Conferences (6) [RSS]
Databases (87) [RSS]
Flex & Flash (109) [RSS]
Fusebox (87) [RSS]
General Development (29) [RSS]
Google (9) [RSS]
Hardware (5) [RSS]
JVM & Java (132) [RSS]
Linux (20) [RSS]
Miscellaneous (254) [RSS]
Performance (8) [RSS]
SeeFusion (36) [RSS]
Shan's Simple Examples (7) [RSS]
User Interface (3) [RSS]
Windows (5) [RSS]
Archives By Poster
Daryl Banttari (10)
Nat Papovich (29)
Patrick Quinn (36)
Shannon Hicks (22)
Steve Nelson (21)
Tyson Vanek (3)
CFSwitch Hunt
We made an interesting discovery in a recent consulting engagement, and we wanted to share what we found with the community. The gist of what we found is that cfswitch, with a string expression, and especially under load, runs dramatically slower than the equivalent cfif-cfelseif-cfelse block. Here''s what happened...
A customer purchased one of our one day remote consulting engagements. They reported an intermittent performance problem that they were unable to pin down. They were already a SeeFusion customer, so we used SeeFusion to generate stack traces on the running requests. This line showed up quite often in the traces we took:
"jrpp-27" prio=5 tid=0x09572cb0 nid=0x12d4 runnable [5da2f000..5da2fdb8]
at java.lang.FloatingDecimal.readJavaFormatString(Unknown Source)
at java.lang.Double.parseDouble(Unknown Source)
Elsewhere in the stack traces we saw evidence of cfswitch usage. So we did some further digging, and sure enough, the customer was using cfswitch tags inside query loops--not an uncommon practice at all. But the switch expressions were all strings. So here''s the kicker. Under the covers, ColdFusion attempts to convert the switch expression to a floating point number, using Java''s parseDouble method. If the conversion works, then ColdFusion uses the expression as a number. If the conversion fails, however, then an exception is thrown, and an exception stack is generated, but then ColdFusion handles the exception and uses the expression as a string. The problem is, that exception throwing and stack generation gets very, very expensive under load.
We cooked up some tests to verify, and sure enough, on average the performance difference between cfswitch with string expressions, and the equivalent cfif-cfelseif-cfelse blocks, was a 10-fold difference. Under load, that will multiply dramatically.
We had the customer convert their cfswitch blocks, and they had an immediate improvement in performance and stability. There were other things left to tune, but this was a primary culprit.
We also found evidence that the floating point conversion might be single-threaded, which would make matters even worse. But the evidence for this wasn''t clear, and there also appeared to be some variation across different VM versions, but we had to move on to other things and couldn''t pursue this other point.
Moral of the story--only use numeric expressions for cfswitch! Otherwise, use equivalent cfif-cfelseif-cfelse blocks. And this is especially true if your code will be running under heavy load.


Your findings fly in the face of the docs so I hope Adobe will take note, investigate this matter and amend the docs if necessary. Now I can return to using lovely CFIF tags. :-)
I'm cringing at my old projects floating around with this not-obvious time bomb in it... all for the sake of code readability...
you contacted any CF engineers about this? the forthcomming CF8 'n' all...
CFSWITCH expression="#arguments.agent#"
CFCASE value="Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"
CFRETURN 20
/CFCASE
CFCASE value="Googlebot/2.1 (+http://www.google.com/bot.html)"
CFRETURN 12
/CFCASE
/CFSWITCH
Will run slower than this one:
CFIF Not CompareNoCase(arguments.agent, 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)')
CFRETURN 20
CFELSEIF Not CompareNoCase(arguments.agent, 'Googlebot/2.1 (+http://www.google.com/bot.html)')
CFRETURN 12
/CFIF
Is there a break point on the amount of cases/CFELSEIFs that will show a performance gain? Such as 10 CFCases or better show the CFSWITCH to be better than 9 CFELSEIFs when dealing with strings.
I also have some of the same questions as others. Is there a tipping point at which one becomes more efficient than the other?
Also, do you have any code you could offer for use in testing?
It should be noted that this is only a problem with <cfswitch> inside of loops, particularly large loops. We got lots of questions on this from Fusebox 3 customers along the lines of--do we need to rewrite all our fbx_switch files!? The answer is very definitely no. You shouldn't see any performance problems with a single pass over a switch statement. However, if you've got a switch statement with a string expression inside even a small loop--say, 100 iterations--then you'll almost certainly see a performance boost by changing those to the equivalent if-else block.
The tipping point would probably vary a bit for different applications. In the case of our customer, the loops were above 1,000 iterations. You'd have to test your system specifically to see what your tipping point is.
I've posted (above) a version of the tests we ran to document the initial performance differences. Later tests were a bit more complicated, but this gives you the gist.