Today I was looking into some code that was running slower than it should, and I happened across this little tidbit:
let $normal :=  try {   xs:int($value)  }  catch($e) {   $value  }
Yes, MarkLogic extends XQuery to add try/catch, and this is a tremendously useful feature, when used in the right place. In this situation, I think the person who wrote the code either didn’t know how to write this a different way, or didn’t realize that try/catch is typically slower. Here it is, properly done:
let $normal := if ($value castable as xs:int) then   xs:int($value) else $value
Does it matter? To find out, let’s ask the profiler. I made a call to the function in CQ and clicked the profiler button, once for each case. Of course, other things happen in the function. In fact, this function calls the above expression over 800 times for a real-world case.
- try/catch — 0.29 seconds
- if/then — 0.029 seconds
That’s an order of magnitude difference.
Moral of the story: as with most languages, exception handling is meant for exception cases. If the catch gets invoked, it should be an unusual case that can’t reasonably be handled by the normal flow of the program.
Tags: anti-pattern, marklogic, xquery
November 14th, 2014 at 12:34 am
Very good point, thanks!