I attempt to provide an answer based on concrete benchmark results. For that I wrote a simple benchmark that compares try-catch to various if-else conditions from simple to more complex. I understand that benchmarks might change a lot depending on the platform. Please comment if you get different results. See the try-catch benchmark here.
First, I try to represent the test suite here in a compact manner. See the link above for full details. There are four test cases, referred later by (index):
- (1) try-catch block that calls a function
lib.foo
with a bit of trigonometric math. No error is ever thrown.
- (2) if-else block that checks the existence of the function by
'foo' in lib
and then calls the function.
- (3) if-else block that checks the existence of the function by
typeof lib['foo'] === 'function'
and then calls the function.
- (4) if-else block that checks the existence of the function by
Object.prototype.hasOwnProperty.call(lib, 'foo')
and then calls the function.
I ran the benchmark a few times on Chrome 87. Although the actual numbers changed from time to time, the results were consistent and can be roughly summarised as follows:
- The try-catch (1) and if-else (2) were almost equivalent in run time. The try-catch (2) was sometimes slower by 1% to 2%.
- The if-else (3) was 75% slower than try-catch (1) or if-else (2).
- The if-else (4) was 90% slower than try-catch (1) or if-else (2).
To clarify, 75% slower means that if the fastest case took 1.0 secs then the 75% slower execution took 1.75 seconds.
As a conclusion, using try-catch in the case where error is never thrown seems to be as efficient as checking any simple condition. If the condition has anything more complex, try-catch is significantly faster.
As a personal note, the conclusion is in line with what I was taught at university. Although it was in the context of C++ the same lesson seems to apply here. If I remember correctly, my lecturer said that try-block was designed to be very efficient, almost invisible efficiency-wise. However, it was the catch-block that was slow and I mean really slow. If an error was thrown then the handling with catch-block took hundreds or even thousands times longer than what could be achieved with if-else block. Therefore, keep your exceptions exceptional.
try
is fairly negligible, but that depends a bit on your definition ofslow
. If you're looking for performance, then there are much better options thentry/catch
. @Roland does a good job of listing a few more good reasons not to use them as well. – Chase