Are exceptions really that slow? - with .NET gRPC
I am building a server base on gRPC. In all docs about gRPC + C# there is the suggested method for error handling to simply throw a
RpcException
to expose information to the client. But I always thought throwing an exception is extremely bad performance wise? I mean throwing an exception for a simple validation failure on the clients input data (REST eq: return BadRequest()
) seems a bit too much, right? Or is that not really a big deal?6 Replies
It's all relative. Anything to do with networks is really slow, much slower than an exception
An exception takes maybe 30us to throw and catch, as a rough number? That's a lot for a tight game loop, but a fraction of the cost of doing anything relating to a network
Exceptions are kinda the go-to method for error handling across different services
Getting information about an exception from your code to someone else's code is really hard and needs to be standardized; thus, exceptions. 'Exceptions are slow' is basically just to discourage people from using exceptions as flow control in their own code (basically exceptions instead of if statements)
I don't know exactly what gRPC is, but it sounds like a separate package/codebase/service which will take any exceptions you throw and send them to the client, which sounds like an appropriate use case (rather than some weird "SendExceptionMessage" method that they might make as an alternative, which would require you to catch your own exceptions if they occurred)
Also... they already have to catch any exceptions you throw, you're already in a try/catch because the service can't break just because you had an exception. I don't know if there is any extra cost if they're already in a try/catch
People get all hung up on "Exceptions should only be used for critical errors because they're so slow", and that's not true at all. An exception is suitable any time that a method can't fulfill the contract given by the method name. If the method is "GetOrders", and the method can't get the orders for any reason (validation failure, no auth, whatever), that's exceptional and an exception is fine. If the method is "ValidateEmail", then finding that the email is invalid is what the method does -- it's part of the contract described by the name "ValidateEmail" -- so an exception would not be appropriate
I don't know if there is any extra cost if they're already in a try/catchTry/catch is essentially free unless an exception needs to be caught IIRC
I didn't even think about that, the obvious answer; if you didn't throw an exception, what would your method return? Exceptions are generally thrown specifically when you can't return what you were asked to return, and throwing means you don't have to return anything
If validation of the input data failed, you can't return their search result because the query wasn't valid. At best you can return null and then you get to deal with trying to handle that everywhere (and differentiate it from an empty result)
Well, OP's example was "BadRequest" -- one return type for successful requests, and other return types for unsuccessful ones
There's
Ok(..)
, BadRequest(..)
, NotFound(..)
, etc. That's how asp.net does itRefit has spoiled me 😛 we just make
ResultModel GetResult(QueryModel query)
(in which case an exception is the only reasonable option when your query fails, and refit turns those into a BadRequest)
But yeah, all that aside, exceptions are fine to use and simplify things significantly and there's a reason they are an option. People telling you not to use exceptions heavily, are probably talking to new coders telling them not to overuse exceptions