Exceptions consume a lot of processing. Truth or legend?

Asked

Viewed 2,194 times

74

I’ve seen shows like this :

if(!clienteExiste(1))
{
    return "Cliente não existe.";
}

and others like that

if(!clienteExiste(1))
{
   throw new Exception("Cliente não existe.");
}

The second code will consume more processing?

  • 12

    Just to spice it up, look what the creator of C++ said about exceptions: "Exception Specifications provide run-time enforcement of which exceptions a Function is allowed to throw. They Were Added at the Energetic Initiative of people from Sun Microsystems. Exception Specifications turned out to be Worse than Useless for Improving readability, Reliability, and performance. They are deprecated (scheduled for Future Removal) in the 2011 standard."

  • 9

    Worth a translation to non-English readers.

  • 1

    If not for the entire process that the Runtime has to realize, the construction try-catch would be slower simply by the construction of the exception object ;)

  • Exceptions have been more in fashion, see that the Go language, which is modern and has had good acceptance, has no exceptions.

  • 3

    @utluiz This refers to specifications of exceptions, which are not the same as exceptions.

  • 1

    @luiscubal Truth, the quote does not talk about Exceptions in general, but about one aspect. What I wanted to point out is that the creator of language mentioned an aspect that impacts performance. So, from what I understand of the phrase, using specified exceptions can generate performance problems. Pity that the author does not delve into the subject. The quote was taken from the book "The C++ Programming Kanguage", 4th edition. The author is none other than Bjarne Stroustrup.

  • 5

    @Philippegioseffi Follows the translation: "The specification of exceptions provides a way to reinforce at runtime which exceptions a function can throw. They were added in an energy initiative of Sun Microsystems staff. The exception specification proved to be worse than useless to improve readability, reliability and performance. They are depreciated (scheduled for future removal) in 2011 standard." (Bjarne Stroustrup, on 98 C++ standard)

  • @utluiz The performance problems are the exception specifications verified at runtime, not the exceptions themselves.

  • 1

    Note that runtime exception specifications do not exist in C#.

  • 1

    @luiscubal I know. The problem is that you can’t edit the first comment. And even if they’re not the same thing, the use of one resource is directly related to the other, isn’t it? I haven’t tried to answer the question. It was just a comment on something that I found curious, mainly because Sun tried to push something from Java to C++.

  • @utluiz "use of one resource is directly related to the other" Yes, to the extent that it makes no sense to have exception specifications without exceptions (except maybe nothrow), but it makes sense to have exceptions without exception specifications. In C# the two are not related because one exists and the other does not. The performance and robustness criticisms of the specifications are not applicable to Java, only to C++. Although I personally hate them even in Java.

  • On Android are very handy to keep the application always working, without appearing the message: "your application stopped" which is very bad for users.

  • Neglecting its indiscriminate use has future consequences. Projects that abuse using the stack to carry through with exceptions across multiple layers have serious consequences on performance. In a time of crisis where many exceptions are thrown occur avalanches of errors that leave the system without resources and so more exceptions are thrown. A snowball. I don’t recommend it as a programming methodology. The correct is to implement the appropriate error treatments and return to the caller without making exceptions. Changing a system that already implements this type of use is impractical most of the time

Show 8 more comments

5 answers

52


Yes.

The. NET uses a processing model in which Try/catch is a "free" operation when there are no exceptions (which is the most common scenario), and the processing is moved to the throw (which slows down as a consequence).

However, the return is no substitute for the throw because they have different meanings.

  1. The return should be used for "normal" results (although it may mean errors, as in the case of TryParse: in the case where errors are so common and expected that it makes sense to use the return);
  2. The throw should be used for possible and recoverable but unusual errors. It should not be used for flow control;
  3. For unrecoverable errors or return nor throw should be used (use System.Environment.Failfast).

In particular, the return is simply not an option in builders.

For unusual scenarios, the exceptions fit perfectly. Because a throw is not slow: several million throws is that they are.

Additionally, these recommendations apply to C#, but not necessarily to other languages.

  • 13

    +1 In short... The problem is not the throw, but rather programming oriented to try/catch.

  • 7

    I make my own the words of @Gabrielgartz and add: use exceptions for exceptional cases, from error! Errors are things like invalid data, problems connecting the database, connection crashes, system unavailable, etc. It seems obvious, but there’s a lot of code out there using exceptions to implement business rule. Then we see pearls like catch ClienteBloqueadoSPCException{} catch ClienteBloqueadoSerasaException{} catch ClienteDesempregadoException{} ... no, no and no!

  • 3

    @Nothingsimpossible To add to' list of situations in which no exceptions should be used: validate input to user.

30

Yes, the second code will consume more processing.

Exceptional situation

But who cares anyway? If something exceptional has actually happened, something out of the normal program flow, this extra processing, which isn’t even that big, depending on what you analyze, won’t degrade the overall performance of the application. At least this consumption will be a very small problem near the bigger problem you had.

Normal flow

But by analyzing the code more coldly it seems to be using an exception to control program flow. It is manipulating business rule. Then it may be that the exception is consuming an amount of processing that affects overall performance, after all the application may have to deal with thousands or millions of customers that do not exist. You multiply something that was almost imperceptible by this greatness and the application gets a cart.

But here comes the question: why use an exception to determine a business rule? This makes no sense. This is not really an exceptional situation. You have only invalid data. If you have a business rule, your structures should know how to communicate with this rule in a traditional way.

An exception should only be used to indicate processing failure and not invalidity of the processed data.

I will not go into this since I have answered a few times on the subject. Read more on better handle exceptions and It is good practice to make an exception in such cases? and Differences between Parse vs Tryparse (good example of how to build an API that reports data invalidity).

Cost of the exception

Note that in . NET, mainly in version 2.0 or later, the cost of the exception was all transferred to the act of casting the exception. There is no significant cost (not zero) to "protect" a chunk of code with try.

This is a feature so complex that it is difficult to measure its performance. Some have tried, as has already been pointed out in other responses, and have not achieved a definitive and reliable result. We can only say in broad lines that the launch (throw) exception is quite slow for normal use of the application.

We can quantify well approximately in a few microseconds to run the launch of an exception itself, on short call piles, in most cases. Which is nothing for a failure situation but is too much for normal flow. Of course, you may have other losses because its use can hamper optimizations, and even worse utilization of the processor cache and page failures in memory. To give a comparison, an exception is faster than an access to SSD or equivalent to several hundred memory accesses.

Misuse

Somewhere, at some point, people started to be induced to think that you can’t never communicate through data structures (which may be only one string, a numerical value such as an enumeration or even a boolean value, and that only the use of the exception is correct. This is not true. If you need to report a data invalidity, a rule violation, some deviation, and this communication requires more complex information, create a structure that can store all necessary information and somehow deliver this structure to those who need to be notified of it, but do not use the exception mechanism for the reasons given above.

Economy of try-catch

If we need to summarize what are the relevant exceptions we have only programming errors and resource failures that the application has no control over.

Some experts think people throw exceptions too much and capture them too.

Many large, robust applications survive well with just one try-catch only to handle programming errors. Use of using which in practice is a try-finally is more necessary. In some cases you may have to capture and treat an exception in a more specific way, for example an access to the database, but even in these cases you will hardly need more than one or two blocks try-catch if you know how to organize the app. Use auxiliary methods to centralize the creations and manipulations of related exceptions that accept the same action or can define actions through parameters.

And if I have a suitable situation for the exception and need performance?

Do not use exceptions. I really can’t see a real case like this, but if there is, you will measure the actual situation of your application, you will understand that you need to improve performance, will note that the release of the exception is consuming much of this processing and will seek a means to use another form of failure communication even if the exception was adequate in that situation. No rule is so golden that it cannot be avoided when it is pertinent.

Related.

  • something you commented makes perfect sense, what the difference in performance since an entire process will be stopped because of an exception, I think the problem of an exception for the customer is worse than the performance.

19

This subject is complex, but to demonstrate which way I prefer to go, follows an excerpt from the source code of Entityframework:

public DbRawSqlQuery<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
{
    Check.NotEmpty(sql, "sql");
    Check.NotNull(parameters, "parameters");

    return
        new DbRawSqlQuery<TElement>(
            new InternalSqlNonSetQuery(_internalContext, typeof(TElement), sql, parameters));
}

This method uses two static calls of a class Check which does the following:

internal class Check
{
    public static T NotNull<T>(T value, string parameterName) where T : class
    {
        if (value == null)
        {
            throw new ArgumentNullException(parameterName);
        }

        return value;
    }

    public static T? NotNull<T>(T? value, string parameterName) where T : struct
    {
        if (value == null)
        {
            throw new ArgumentNullException(parameterName);
        }

        return value;
    }

    public static string NotEmpty(string value, string parameterName)
    {
        if (string.IsNullOrWhiteSpace(value))
        {
            throw new ArgumentException(Strings.ArgumentIsNullOrWhitespace(parameterName));
        }

        return value;
    }
}

See how simple parameter checks are handled: with Exceptions. In my opinion use Excpetions To divert the code is fundamental, it is a matter of design and architecture, and when it comes to this subject one should not prioritize who consumes more or less processing. If that were so, we wouldn’t have high-level languages, we’d be writing code in Assembly.

We should prioritize code writing with good standards, because if we don’t do that, the gain that we seem to take in a single call, like the case of this question, will be lost with a poorly written code that in a short time may become heavy and slow for reasons we will not be able to find.

Finally a small article in English citing the following:

Do not use error codes because of Concerns that exceptions Might affect performance negatively.

Use design to mitigate performance issues.

Translated to:

Do not use error codes for concerns that exceptions may negatively affect the performance.

Use design to investigate performance issues.

At the end the article describes two patterns for the best use of Exceptions.

  • Good! I prefer a readable code and where I can easily find any possible problem than a very efficient code where, when some error occurs, it is practically impossible to discover its origin.

16

8

The time "lost" in Exceptions is very small compared to code readability. Other developers should look at your code and clearly understand that it is an error handling. Even so, no . NET, Exceptions are free when everything goes right, if there is an exception the lost time will not make a difference since the execution will stop anyway.

Use if for decision making and Exceptions for error handling.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.