How slow are .NET exceptions?
Asked Answered
V

14

153

I don't want a discussion about when to and not to throw exceptions. I wish to resolve a simple issue. 99% of the time the argument for not throwing exceptions revolves around them being slow while the other side claims (with benchmark test) that the speed is not the issue. I've read numerous blogs, articles, and posts pertaining one side or the other. So which is it?

Some links from the answers: Skeet, Mariani, Brumme.

Vitrine answered 2/10, 2008 at 12:9 Comment(2)
there are lies, damn lies and benchmarks. :)Letter
Unfortunately, several high voted answers here missed that the question is asking "how slow are exceptions?", and specifically asked to avoid the topic of how often to use them. One simple answer to the question which as actually asked is.....On Windows CLR, exceptions are 750 times slower than return values.Joscelin
C
218

I'm on the "not slow" side - or more precisely "not slow enough to make it worth avoiding them in normal use". I've written two short articles about this. There are criticisms of the benchmark aspect, which are mostly down to "in real life there'd be more stack to go through, so you'd blow the cache etc" - but using error codes to work your way up the stack would also blow the cache, so I don't see that as a particularly good argument.

Just to make it clear - I don't support using exceptions where they're not logical. For instance, int.TryParse is entirely appropriate for converting data from a user. It's inappropriate when reading a machine-generated file, where failure means "The file isn't in the format it's meant to be, I really don't want to try to handle this as I don't know what else might be wrong."

When using exceptions in "only reasonable circumstances" I've never seen an application whose performance was significantly impaired by exceptions. Basically, exceptions shouldn't happen often unless you've got significant correctness issues, and if you've got significant correctness issues then performance isn't the biggest problem you face.

Cleavers answered 2/10, 2008 at 12:15 Comment(19)
unfortunately, people are told exceptions are free, use them for trivial 'correct' functionality, they should be used as you say, when things have gone wrong - in 'exceptional' circumstancesLetter
Yes, people should certainly be aware that there's a performance cost associated with using exceptions inappropriately. I just think it's a non-issue when they are used appropriately :)Cleavers
Another point worth of note: tryparse should be used when you can recover from a failure, otherwise parse will be faster than "if(!tryparse) throw"Gorham
For once Jon Skeet is incorrect. I've tuned many C# applications and removing Exceptions from happy-path logic is low hanging fruit. One very high traffic website's load time was doubled by this tuning alone. Use Perfmon; if you see Exceptions/sec in the 200+ range you've got a trivial performance boostDisplume
@PaulLockwood: I would say that if you've got 200+ exceptions per second, you're abusing exceptions. It's clearly not an "exceptional" event if it's occurring 200 times per second. Note the last sentence of the answer: "Basically, exceptions shouldn't happen often unless you've got significant correctness issues, and if you've got significant correctness issues then performance isn't the biggest problem you face."Cleavers
200+ per second happens way more often than one would imagine. I've tuned at many companies, virtually every high traffic site has had that problem. I saw a site with ~30 quad core servers have over 1000/s once! (only six in DMZ handling direct web traffic but still...) From experience Exceptions are slow, but like Reflection if it happens infrequently then its no big dealDisplume
@PaulLockwood: My point is that if you've got 200+ exceptions per second, that probably already indicates that you're abusing exceptions. It doesn't surprise me that that's often the case, but it means that the performance aspect wouldn't be my first concern - the abuse of exceptions would be. Once I'd removed all inappropriate uses of exceptions, I wouldn't expect them to be a significant part of performance.Cleavers
agree. Developers can abuse many things and get away with it (thanks to modern hardware/compilers). Exceptions -like Reflection- needs little abuse before having significant impactDisplume
it's scarry that this answer is voted so high. Exceptions (when compared to return values) are INCREDIBLY slow in .NET. My benchmark shows they are about 1400x slower than return values. (see below)Joscelin
@DavidJeske: You've missed the point of the answer. Obviously throwing an exception is much slower than returning a normal value. No-one's arguing that. The question is whether they're too slow. If you're in a suitable situation for throwing an exception and that's causing a performance problem, then you've probably got bigger problems - because it suggests that there's a huge amount wrong with your system. Normally, the problem is really that you're using exceptions when they're inappropriate to start with.Cleavers
One fun misuse of exceptions is in PowerShell where break and continue are implemented that way and hence are horribly slow. Certainly a cost you wouldn't expect when writing a loop using those constructs.Bundle
@Jon Skeet - and yet the original question is not about when to use exceptions, but about their performance. Exceptions in windows CLR are dog slow, there is no question. Whether someone is using them too much or not is a separate issue. In some runtimes and languages, exceptions are an acceptable non-local program control for a variety of circumstances. In CLR, they are not. In particular, they are too slow to ever use in library code, because you never know how frequently someone needs to call your library.Joscelin
@DavidJeske: But their performance only matters in context, IMO. When used appropriately, they are fast enough and will not hurt your application's performance. When used in the wrong place, they are slow and will kill it completely.Cleavers
On Windows CLR, exceptions are 750 times slower than return values (see my answer). This benchmark, and the conclusion they are "not slow", is invalid.Joscelin
@DavidJeske - This is just like the gun control issue that is rife in the USA. Guns are safe if used appropriately. Exceptions are fast is used appropriately. Can guns be dangerous? Yes. Can exceptions be slow? Yes. Gosh darn we're lucking that there's no Amendment for the right to throw exceptions.Luckey
In my release mode benchmark, .NET exception thrown and caught in the same method takes about 15 microseconds, or 0.000015 seconds.Horsecar
@Luckey No, CLR exceptions are always slow. If they are used sparingly, that slowness may not be a problem. Managing this can be troublesome when it crosses library boundaries. For example, don't use Dictionary indexers and KeyNotFound exception when keys might frequently be missing, because it will dog your app. Instead use TryGetValue. However, not all libraries will supply both exception and non-exception versions of every API. It's a schitzophrenic approach to API design when everything has to be done twice.Joscelin
@DavidJeske - My point was that if they're used sparingly they're OK, but in reality they are overused by most developers.Luckey
I think my favorite point comment here is when @JonSkeet says "performance only matters in context". If you're doing floating point math for some graphical or theoretical computation, then yes, maybe exception cost matters. If you have a connected application making data or service calls measured in ms, then you probably won't even remotely notice an exception measured in ns.Pavkovic
L
37

There is the definitive answer to this from the guy who implemented them - Chris Brumme. He wrote an excellent blog article about the subject (warning - its very long)(warning2 - its very well written, if you're a techie you'll read it to the end and then have to make up your hours after work :) )

The executive summary: they are slow. They are implemented as Win32 SEH exceptions, so some will even pass the ring 0 CPU boundary! Obviously in the real world, you'll be doing a lot of other work so the odd exception will not be noticed at all, but if you use them for program flow expect your app to be hammered. This is another example of the MS marketing machine doing us a disservice. I recall one microsoftie telling us how they incurred absolutely zero overhead, which is complete tosh.

Chris gives a pertinent quote:

In fact, the CLR internally uses exceptions even in the unmanaged portions of the engine. However, there is a serious long term performance problem with exceptions and this must be factored into your decision.

Letter answered 2/10, 2008 at 12:33 Comment(1)
I can mention this in real-world tests, where a nullable type is causing an exception to be raised many times in a "this is normal program flow", that has ended up with significant performance problems. Alwyas remember, exceptions are for exceptional cases, don't believe anyone who says otherwise or you'll end up with a github thread like that one!Letter
O
9

I have no idea what people are talking about when they say they are slow only if they are thrown.

EDIT: If Exceptions aren't thrown, then that means you are doing new Exception() or something like that. Otherwise the exception is going to cause the thread to be suspended, and the stack to be walked. This may be Ok in smaller situations, but in high-traffic websites, relying on exceptions as a workflow or execution path mechanism will certainly cause you performance problems. Exceptions, per se, aren't bad, and are useful for expressing exceptional conditions

The exception workflow in a .NET app uses first and second chance exceptions. For all exceptions, even if you are catching and handling them, the exception object is still created and the framework still has to walk the stack to look for a handler. If you catch and rethrow of course that is going to take longer - you are going to get a first-chance exception, catch it, rethrow it, causing another first-chance exception, which then doesn't find a handler, which then causes a second-chance exception.

Exceptions are also objects on the heap - so if you are throwing tons of exceptions, then you are causing both performance and memory issues.

Furthermore, according to my copy of "Performance Testing Microsoft .NET Web Applications" written by the ACE team:

"Exception handling is expensive. Execution of the involved thread is suspended while CLR recurses through the call stack in search of the right exception handler, and when it is found, the exception handler and some number of finally blocks must all have their chance to execute before regular processing can be performed."

My own experience in the field showed that reducing exceptions significantly helped performance. Of course, there are other things you take into account when performance testing - for example, if your Disk I/O is shot, or your queries are in the seconds, then that should be your focus. But finding and removing exceptions should be a vital part of that strategy.

Offside answered 2/10, 2008 at 12:44 Comment(8)
Nothing you have written contradicts the claim that exceptions are only slow if they're thrown. You've only talked about situations where they are thrown. When you've "significantly helped performance" by removing exceptions: 1) Were they true error conditions, or just user error?Cleavers
2) Were you running under the debugger, or not?Cleavers
The only possible thing that you can do with an exception if not throwing it is create it as an object, which is meaningless. Being under the debugger or not doesn't matter - it is still going to be slower. Yes, there are hooks that will happen with a debugger attached, but it is still slowOffside
So Jon - I think what you are saying is that the occasional exception is no big deal. I agree with you. But in perf calls I did with large customers, we checked first for "debug" enabled in their web apps, and then how many exceptions they were throwing. It does matter.Offside
It's certainly slower than using a return code, but how much slower matters a lot. If throwing an exception takes a millisecond, then that occurring a few thousand times an hour doesn't matter. If it takes a second, it matters a lot!Cleavers
How many exceptions were your customers throwing, btw? Don't forget that by default Response.Redirect throws an exception...Cleavers
I know - I was part of the Premier team at MSFT. :) Let's just say, lots - thousands a second in some extreme cases we saw. Nothing like connecting with a live debugger and just seeing exceptions as fast as you could read. Ex's are slow - so is connecting to a DB, so you do it when it makes sense.Offside
Cory, I think the point of "only slow when they're thrown" is that you don't have to worry about performance because of the mere presence of catch/finally blocks. I.e. these in themselves don't cause a performance hit, only the occurrence of an actual exception instance.Marvelous
F
7

The argument as I understand it is not that throwing exceptions are bad they are slow per se. Instead, it is about using the throw/catch construct as a first class way of controlling normal application logic, instead of more traditional conditional constructs.

Often in normal application logic you perform looping where the same action is repeated thousands/millions of times. In this case, with some very simple profiling (see the Stopwatch class), you can see for yourself that throwing an exception instead of say a simple if statement can turn out to be substantially slower.

In fact I once read that the .NET team at Microsoft introduced the TryXXXXX methods in .NET 2.0 to many of the base FCL types specifically because customers were complaining that performance of their applications was so slow.

It turns out in many cases this was because customers were attempting type conversion of values in a loop, and each attempt failed. An conversion exception was thrown and then caught by an exception handler that then swallowed the exception and continued the loop.

Microsoft now recommend the TryXXX methods should be used particularly in this situation to avoid such possible performance issues.

I could be wrong, but it sounds like you are not certain about the veracity of the "benchmarks" you have read about. Simple solution: Try it out for yourself.

Foxtail answered 2/10, 2008 at 12:19 Comment(3)
I thought that internatlly those "try" functions use exceptions as well?Colleencollege
These "Try" functions do not throw exceptions internally for a failure to Parse the input value. However they still throw exceptions for other error situations, such as ArgumentException.Foxtail
I think this answer gets closer to the heart of the issue than any other. Saying 'use exceptions only in reasonable circumstances' doesn't really answer the question -- the real insight is that using C# exceptions for control flow is much slower than the usual conditional constructs. You could be forgiven for thinking otherwise. In OCaml, exceptions are more or less a GOTO and the accepted way of implementing break when using the imperative features. In my particular case, replacing in a tight loop int.Parse() plus try/catch vs. int.TryParse() gave a significant performance boost.Cyprinoid
L
4

My XMPP server gained a major speed boost (sorry, no actual numbers, purely observational) after I consistently tried to prevent them from happening (such as checking if a socket is connected before try to read more data) and giving myself ways to avoid them (the mentioned TryX methods). That was with only about 50 active (chatting) virtual users.

Legislate answered 2/10, 2008 at 12:51 Comment(1)
Numbers would be useful, unfortunately :( Things like socket operations should vastly outweigh exception costs, certainly when not debugging. If you ever benchmark it fully, I'd be really interested to see the results.Cleavers
T
3

Just to add my own recent experience to this discussion: in line with most of what is written above, I found throwing exceptions to be extremely slow when done on a repeated basis, even without the debugger running. I just increased the performance of a large program I'm writing by 60% by changing about five lines of code: switching to a return-code model instead of throwing exceptions. Granted, the code in question was running thousands of times and potentially throwing thousands of exceptions before I changed it. So I agree with the statement above: throw exceptions when something important actually goes wrong, not as a way of controlling application flow in any "expected" situations.

Thalassic answered 25/3, 2011 at 12:17 Comment(0)
O
3

But mono throws exception 10x faster than .net standalone mode, and .net standalone mode throws exception 60x faster than .net debugger mode. (Testing machines have same CPU model)

int c = 1000000;
int s = Environment.TickCount;
for (int i = 0; i < c; i++)
{
    try { throw new Exception(); }
    catch { }
}
int d = Environment.TickCount - s;

Console.WriteLine(d + "ms / " + c + " exceptions");
Ori answered 24/2, 2012 at 5:38 Comment(0)
G
2

I have never had any performance problem with exceptions. I use exceptions a lot -- I never use return codes if I can. They are a bad practice, and in my opinion, smell like spaghetti code.

I think it all boils down to how you use exceptions: if you use them like return codes (each method call in the stack catches and rethrows) then, yeah, they will be slow, because you have overhead each single catch/throw.

But if you throw at the bottom of the stack and catch at the top (you substitute a whole chain of return codes with one throw/catch), all costly operations are done once.

At the end of the day, they are a valid language feature.

Just to prove my point

Please run the code at this link (too big for an answer).

Results on my computer:

marco@sklivvz:~/develop/test$ mono Exceptions.exe | grep PM
10/2/2008 2:53:32 PM
10/2/2008 2:53:42 PM
10/2/2008 2:53:52 PM

Timestamps are output at the beginning, between return codes and exceptions, at the end. It takes the same time in both cases. Note that you have to compile with optimizations.

Gorham answered 2/10, 2008 at 12:26 Comment(0)
G
2

If you compare them to return codes they are slow as hell. However as previous posters stated you don't want to throw in normal program operation so you only get the perf hit when a problem occurs and in the vast majority of cases performance no longer matters (as the exception implies a road-block anyway).

They're definately worth using over error codes, the advantages are vast IMO.

Guyton answered 2/10, 2008 at 12:27 Comment(0)
J
2

On the Windows CLR, for a depth-8 call chain, throwing an exception is 750-times slower than checking and propagating a return value. (see below for benchmarks)

This high cost for exceptions is because the windows CLR integrates with something called Windows Structured Exception Handling. This enables exceptions to be properly caught and thrown across different runtimes and languages. However, it's very very slow.

Exceptions in the Mono runtime (on any platform) are much faster, because it does not integrate with SEH. However, there is functionality loss when passing exceptions across multiple runtimes because it doesn't use anything like SEH.

Here are abbreviated results from my benchmark of exceptions vs return values for the Windows CLR.

baseline: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.25 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.5 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 0.75 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 1 (0), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0 (0), time elapsed 13.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.25 (249999), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.5 (499999), time elapsed 16.0009 ms
retval_error: recurse_depth 5, error_freqeuncy 0.75 (999999), time elapsed 16.001 ms
retval_error: recurse_depth 5, error_freqeuncy 1 (999999), time elapsed 16.0009 ms
retval_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 20.0011 ms
retval_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 21.0012 ms
retval_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 24.0013 ms
exception_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 31.0017 ms
exception_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 5607.3208     ms
exception_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 11172.639  ms
exception_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 22297.2753 ms
exception_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 22102.2641 ms

And here is the code..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {

public class TestIt {
    int value;

    public class TestException : Exception { } 

    public int getValue() {
        return value;
    }

    public void reset() {
        value = 0;
    }

    public bool baseline_null(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            return shouldfail;
        } else {
            return baseline_null(shouldfail,recurse_depth-1);
        }
    }

    public bool retval_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                return false;
            } else {
                return true;
            }
        } else {
            bool nested_error = retval_error(shouldfail,recurse_depth-1);
            if (nested_error) {
                return true;
            } else {
                return false;
            }
        }
    }

    public void exception_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                throw new TestException();
            }
        } else {
            exception_error(shouldfail,recurse_depth-1);
        }

    }

    public static void Main(String[] args) {
        int i;
        long l;
        TestIt t = new TestIt();
        int failures;

        int ITERATION_COUNT = 1000000;


        // (0) baseline null workload
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    t.baseline_null(shoulderror,recurse_depth);
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "baseline: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }


        // (1) retval_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    if (!t.retval_error(shoulderror,recurse_depth)) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "retval_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }

        // (2) exception_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    try {
                        t.exception_error(shoulderror,recurse_depth);
                    } catch (TestException e) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "exception_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));         }
        }
    }
}


}
Joscelin answered 21/3, 2012 at 4:40 Comment(2)
Aside from missing the point of the question, please don't use DateTime.Now for benchmarks - use Stopwatch, which is designed for measuring elapsed time. It shouldn't be an issue here as you're measuring reasonably long time periods but it's worth getting into the habit.Cleavers
On the contrary, the question is "are exceptions slow", period. It specifically asked to avoid the topic of when to throw exceptions, because that topic obscures the facts. What are the performance of exceptions?Joscelin
L
1

In release mode the overhead is minimal.

Unless you are going to be using exceptions for flow-control (example, non-local exits) in a recursive fashion, I doubt you will be able to notice the difference.

Lindsaylindsey answered 2/10, 2008 at 12:13 Comment(0)
P
1

You pretty much answered your own question I think. You, and pretty much everyone that has an understanding of them, know they're slow. It's a 100% fact, but as many others have pointed out, the context is what matters 100% as to when to use them. Writing a non server application? you'll never notice a difference. Writing a website public API where a malformed client request can trigger an exception on the backend? That's a recipe for disaster on an order of magnitude that is multiplied by the requests/second. Backends are pegged more times than the penny pony at the grocery store. The problem with that, though, is the BCL/other libraries will throw exceptions you have no control over, so you have to middle man/crossing guard things that would trigger those exceptions before they got to the BCL. There are cases where you have absolutely no defense at all. Such as reaching out to a MongoDB database with the MongoClient. All of the MongoCollection.*Async functions will throw exceptions if they dont succeed in certain scenarios, but it doesnt throw many at all, and I'm pretty sure these scenarios are on the rare end of the spectrum(which shifts this towards the context part of the situation). I could also be wrong, though. I'd just assume they only threw on rare occasions. As you pointed out, you know they're slow, so it's only common sense that you use them in contexts that require things to not be slow. Plain and simple.

Privilege answered 1/10, 2020 at 7:10 Comment(0)
I
0

One quick note here on the performance associated with catching exceptions.

When the execution path enters a 'try' block, nothing magical happens. There is no 'try' instruction, and no cost associated with either entering or exiting the try block. Information about the try block is stored in the method's metadata, and this metadata is used at runtime whenever an exception is raised. The execution engine walks down the stack looking for the first call that was contained in a try block. Any overhead associated with exception handling occurs only when exceptions are thrown.

Insightful answered 23/10, 2008 at 8:55 Comment(1)
However, the presence of exceptions can impact optimization - methods with explicit exception handlers are harder to inline, and instruction reordering is limited by them.Depside
H
-1

When writing classes/functions for others to use it appears to be difficult to say when exceptions are appropriate. There are some useful parts of BCL that I had to ditch and go for pinvoke because they throw exceptions instead of returning errors. For some cases you can work around it but for others like System.Management and Performance Counters there are usages where you need to do loops in which exceptions are thrown by BCL frequently.

If you are writing a library and there's a remote possibility that your function may be used in a loop and there's a potential for large amount of iterations, use the Try.. pattern or some other way to expose the errors beside exceptions. And even then, it's hard to say how much your function will get called if it's being used by many processes in shared environment.

In my own code, exceptions are only thrown when things are so exceptional that its necessary to go look at the stack trace and see what went wrong and then fix it. So I pretty much have re-written parts of BCL to use error handling based on Try.. pattern instead of exceptions.

Holst answered 23/3, 2014 at 2:12 Comment(1)
This doesn't seem to fit the poster's "I don't want a discussion about when to and not to throw exceptions" statement.Ineffectual

© 2022 - 2024 — McMap. All rights reserved.