Often, but not always, the object is a constant and its identity is
known at compile time. Is it worthwhile creating unique subclasses of
CatchPoint, one for each such manifest thrown object, so that the
above test can be omitted?
--
GMail doesn't have rotating .sigs, but you can see mine at
http://www.ccil.org/~cowan/signatures
I think you should see quite a performance improvement if you do this.
So, as long as you aren't generating very large numbers of these
specialised classes, I think I'd do it.
On a related topic, John Rose has written about efficient use of
Exceptions (http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive).
This may not be relevant to what you are doing here but it's useful
stuff to know.
John Wilson
This is what we do in JRuby; all Ruby exceptions (RubyException type in
Java) get wrapped in a RuntimeException descendant (RaiseException), and
in-language rescue/catch clauses then catch all RaiseExceptions and
perform the appropriate operation (which in Ruby is equivalent to a
case/when statement). For general exception handling, this is basically
the only way, since at compile time it's impossible to know in Ruby what
types are actually being caught. Your case is different there.
>> Often, but not always, the object is a constant and its identity is
>> known at compile time. Is it worthwhile creating unique subclasses of
>> CatchPoint, one for each such manifest thrown object, so that the
>> above test can be omitted?
If omitting the test does not change the semantics of your language,
that I'd suspect it would be very useful. And...
> I think you should see quite a performance improvement if you do this.
> So, as long as you aren't generating very large numbers of these
> specialised classes, I think I'd do it.
it would probably also improve performance. But if you're not
implementing something like non-local flow control, which is very
sensitive to exception handling cost, perhaps it doesn't make a difference?
> On a related topic, John Rose has written about efficient use of
> Exceptions (http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive).
> This may not be relevant to what you are doing here but it's useful
> stuff to know.
I don't think it's directly relevant, unless John C is using exceptions
for flow control.
What I would be interested in hearing is if N catches are more expensive
than one catch, or if catching at all already has done the damage and
adding additional catches doesn't make much difference. For exceptions
bubbling out from deep inside an API, in JRuby it will essentially be
caught at several places. Though we have no real way to avoid that, it
would be useful to know the real cost.
Twould be a useful benchmark to run...
- Charlie
> I don't think it's directly relevant, unless John C is using exceptions
> for flow control.
The facility is used under the covers for flow control, but is also
exposed directly to the user. I'm planning, based on what you two
have written, to implement four cases, in increasing order of
generality. I'm writing them down here in case they help anyone else.
Note that the style is "catch (tag) { body }" and "throw(tag,
value)", where in both cases "tag" is evaluated at run time, so the
tag being thrown is independent of the value being returned.
1) If the thrown value is manifest, and
1a) the catch is the top-level expression in the same procedure, then
implement the throw as "return value;".
1b) the throw is in the same procedure as the catch (but not in any
nested procedure), then implement it as "temp = null; foo: do { ...;
temp = value; break foo; ...} until true;".
1c) the catch and the throw are in different procedures, then use the
unique instance of a unique subclass of CatchPoint.
2) If the thrown value is not manifest, use an instance of CatchPoint
directly, storing the run-time object in its sole field. CatchPoint
suppresses tracebacks.
Of course when I say "manifest", I mean "manifest at both the catcher
and the thrower".
I should also add that a native Java exception can be caught; things
are arranged so that the catcher sees the thrown tag as the
exception's class (that being a unique object) and the thrown value as
the exception object itself.
> What I would be interested in hearing is if N catches are more expensive
> than one catch, or if catching at all already has done the damage and
> adding additional catches doesn't make much difference.
I'd like to know that too.