|
One of the rules the .NET was designed with in mind was that exceptions are only for exceptional situations. Therefore performance doesn't matter. The same thing can be noticed with delegates.
But the above assumption is a piece of crap. It is quite common to break the loop using exceptions in functional languages. Exceptions are treated there as a form of structuring program. Nobody would do it in .NET.
However there are cases when using exceptions would simplify program structure a lot, and I still cannot do it, because exceptions are soooooo slow.
I've been writing my MSc thesis right (Let S be a partial preorder on type variables...), I mentioned it some time ago here. I was clearly wrong assuming I've got everything done ;)
Anyway in addition to the theoretical background, I want to implement it. Until now I've created about 150k of code without even compiling it, which doesn't seem a good thing, but I cannot figure out a way to test pieces separately. Now what does it all have in common with exceptions?
Well, in the new typing engine it will be possible to save entire state on the stack, type some expression, inspect it, discard and pop state from the stack. All side-effect free. It can be usable for macros. It also simplifies things in many places -- for example to see what 'x' is we need to check for 'x' (a local), 'this.x', 'System.x', 'System.Foobar.x' and so on. This is easily done using the above mechanism (save, try typing, see if there were an error, restore and if there were no error run typing again).
But the most important point where it is used is overload resolution -- we need to try several possible resolution of the symbol being called.
Now, handling errors (user errors in programs) as exceptions in compilers is quite reasonable -- you can catch them for example in method compilation procedure and get just-one-error-in-a-method behavior, you can catch them somewhere else. And in general there is no performance issue here -- if any single throw will result in an error message, then there is no performance problem, exceptions aren't that slow.
But now, when we have this stacked typing, it is common to have ,,user errors'' in normal execution paths. In overload resolution it is common to just one of several possibilities to be error-free. So we cannot use exceptions in overload resolution. And if we cannot use exceptions in overload resolution, this is as bad as we couldn't have used them at all. We're back in the good ol' C model of checking return values for errors. That's why I don't think that exceptions should be that slow.
What does it mean ,,that'' slow? Well under mono/amd64 throwing and catching an exceptions takes about 18k cycles. It's quite similar on mono/x86. The other implementation I tasted wasn't better. All this means, that using my super hiper turbo fast machine I'm able to throw 100k exceptions per second. So using it for any other purposes then error reporting and cannot happen kind of situation is a performance suicide.
And here is the piece of (C#, hehe) code that I used for the tests.
From: malekith (81.219.231.36)
The first comment.
From: malekith (81.219.231.36)
Testing national characters. żółw brzmi w czcinie w szczebrzeszynie.
From: malekith (81.219.231.36)
yet another test
From: identy (80.58.19.46)
good work, GCC to .NET? when?
From: malekith (81.219.231.36)
I don't get it. How does it relate to GCC?
From: Bjarne Nilsson (82.116.80.11)
Pardon my ignorance I'æm new to programing, but why do you want to throe an handelk exeptions/sec. If I did not misunderstand a biginers book on c# (sorry forgot the title) corectly an exeption shold only be useed if en error cannot be recoverd in anuther way/ex: a read error from a disk). So my question is whet kkind of software are you making that creates that kind of problems 100k times/second?
From: nazgul (156.17.160.1)
What you describe is a usage pattern of exceptions in C# suggested by its creators. But as Michal described above one could imagine using exceptions for other cases than unrecoverable errors.
The mentioned example was that algorithm could "try" one of many options it could choose and catch exception if the operation failed. It is a problem if algorithm knows that particular option is wrong far from the place where it was choosen - it
must return from several functions then. Using exception for this would a be quite
elegant design, but unfortunately because of performance issues of exceptions in .NET implementations it is not.
From: simtam (217.74.68.2)
One can imagine "lightweight" exceptions that are compiled to exception-free .NET code, for example by instrumenting code with additional return values. Do you consider adding such feature to Nemerle? I wonder if it is possible to use the macro system to perform such instrumentation.
From: malekith (81.219.231.36)
I personally thought about this some time ago. This would be more or less
kind of functional goto. And the compilation would probably result in
lots of gotos :-) But this is not bad, once you've got the source form
readable.
I think that this may be interesting also from the scientific point of
view (as a kind of program transformation/optimization). I intend to take
care of it some time in the future (but rather in the loooong future,
not now), if nobody will do it before.
I also recall something along this lines on the OCaml list, a year ago or so.
But it didn't catch much attention, since OCaml has very fast general
exception handling.
As for the macro usage here -- it depends on exactly what are you trying
to do, but I guess it would be hard, especially without gotos.
From: MattiasW (83.226.138.26)
Java exception is also very slow. In Java there is a trick to make exceptions faster:
http://www.dina.kvl.dk/~sestoft/papers/performance.pdf
You can prevent the generation of this stack trace by overriding method fillInStackTrace in subclasses of Exception, as shown below. This makes creation exception instances roughly 10 times faster.
class MyException extends Exception {
public Throwable fillInStackTrace() {
return this;
}
}
From: tamiflu (220.64.88.9)
Good post, very useful i like it very much
From: (219.93.174.106)
Best of the text i read about a problem.
From: (220.194.26.10)
We are wellocme to it's configuration.
From: (213.114.21.87)
Wellcome to the real world.
From: (218.28.14.73)
Need to be readed.
From: (69.31.86.8)
Your article is prety nice. It's a pity that i didn't see it more later.
From: (69.31.86.8)
Persone los pioneros non rabata. Great...