Switch find-zero method if convergence fails without try-catch

I have an inner loop which solves a simple equation using find_zero(), currently with the default Order0() method at a plausible starting value. 99.99% of the time, this works smoothly with no issues. However, occasionally this does fail to converge, and when this happens I’d like to switch method to a bisection approach with a very large interval. The obvious method would seem to be:

try
    result = find_zero(f, ini)
catch
    result =  find_zero(f, [0, Big_Number])
end

However, my concern is that try/catch apparently slows down code significantly (e.g. here) even when try completes successfully. This would be lethal to my code, since this inner loop is being run an awful lot. So my questions are:

  • Is there still a significant performance penalty to try/catch as of 1.5.3?
  • Is there another way to achieve “try algorithm A, if it fails try B” without compromising performance?

I’m assuming that you are talking about find_zero from Roots.jl. You could easily modify one line of the code to return the exception instead of throwing it. Then check the return typen instead of the trycatch.

As far as I know, try/catch in Julia is still slow, and the convention is to only throw for serious problems, and to indicate problems via the return type when speed matters.

A “clean” way of doing this would be too add a keyword argument throw_on_failure to find_zero. This argument could have a default value of Val(true), but setting it to Val(false) would cause the exception to be returned instead of thrown. (This causes a type instability in the return value, but that instability is resolved as soon as the calling function verifies that the returned value is indeed a Number.)

2 Likes

I made an issue for this with a PR to do this a slightly different way.

https://github.com/JuliaMath/Roots.jl/issues/196