RubyFlow The Ruby and Rails community linklog

How slow are (Ruby) Exceptions?

If you are used to benchmark your Ruby scripts or if you ever had to improve the performance of some strategic tasks, then this post won’t tell you nothing new because you should already know that Ruby Exceptions are slow. And this is not really a Ruby problem: .NET Exceptions are slow, JAVA Exceptions are slow just because the begin/raise/rescue (or try/throw/catch) architecture is slow by nature.

Comments

Actually if you do a bit more digging I think you will find that .NET exceptions have virtually no overhead in normal execution flow, they are slow in the case of an actual exception occurring.. MS have quite a detailed document about the design decisions behind their emphasis on exceptions.

Short version, in .NET one shouldn’t be timid about using exceptions as they wont present an overhead, BUT you shouldn’t use exceptions for regular flow control as you will carry an overhead in the processing of an exception which IS slow.

I can’t speak to Java or Ruby on this matter.

And that’s why they should be used to handle exceptional cases and are not a substitute for proper flow control.

@Guy Murphy: .NET exceptions are still an order of magnitude slower than just returning a message or collecting your own errors. The reason is that it needs to get the stack out and does a bunch of work. This is cool if that also holds actual helpful information but otherwise they should be avoided. For example an invalid login doesn’t warrant an exception because it’s not an exceptional event from a code POV IMO and so on.

People who don’t know what they are talking about shouldn’t be allowed to write a blog like they are an expert. Learn how to really benchmark before you talk about this subject.

These three classes don’t do the same thing. In particular the one using exception handling attempts a to_i conversion for each value, no matter what the expense of that conversion. The other two example classes prune unlikely cases out, only doing the conversion when absolutely necessary.

In my experience, exceptions can also cause a large amount of garbage object production (mostly strings, if I remember correctly). This causes the garbage collection to run more slowly. By using IO.eof? before attempting an asynchronous read, I was able to remove one thrown exception per frame of the Luz music visualizer, and dramatically improved the GC pause-the-world problem.

This should be obvious but benchmark/profile Ruby only to find clearly dumb stuff in your code. If you start ignoring language features or writing things the long way round just because its faster then you need to revisit the “optimized for humans” mantra.

If your regular Ruby isn’t fast enough then re-engineer, wrap (or let ruby-ffi do it for you) one of the millions of C libraries or pick a faster language. All of these are better options than spending your afternoon benchmarking language features for tiny speed gains :)

Post a comment

You can use basic HTML markup (e.g. <a>) or Markdown.

As you are not logged in, you will be
directed via GitHub to signup or sign in