Tech Support > Computers & Technology > Programming > Low-overhead exceptions
Low-overhead exceptions
Posted by Jonathan Bartlett on December 14th, 2005


Does anyone know of a language with very-low-overhead exceptions? For
example, one where using them for flow control would not be problematic?
I know its a wierd question.

Jon

Posted by Oliver Wong on December 14th, 2005



"Jonathan Bartlett" <johnnyb@eskimo.com> wrote in message
news:43a098c5@news.tulsaconnect.com...
It sounds like you're "Asking The Wrong Question(tm)". Presumably you
want a low-overhead-exceptions language because you're trying to accomplish
something else. For example, perhaps you're trying to quickly break out of a
recursive method call. If so, why not just ask for languages which support
quickly breaking out of recursive method calls? (But again this might also
be the "Wrong Question", so you might have to dwelve further deeper back and
look at what you're REALLY trying to accomplish).

Otherwise you risk getting suggestions for languages whose exception
behaviour might not be what you expect (e.g. that they are not "catcheable"
elsewhere in the code, but rather get handled in-place).

- Oliver



Posted by Artie Gold on December 15th, 2005


Jonathan Bartlett wrote:
IIRC there's a comparison out there of Common Lisp's condition system
vs. exceptions in other languages and the CL conditions are of
considerably lighter weight. [Perhaps I can dig up the URL, but I
haven't found it just yet.]

HTH,
--ag

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"

Posted by Jonathan Bartlett on December 15th, 2005


Actually, what I'm trying to do is teach continuations by introducing
additional uses of exceptions first, and then generalizing from there.
But, I wanted to use a language where such a thing might actually be a
legitimate use, so I wasn't just developing antipatterns in someone's mind.

Originally I was going to do Java exceptions, but they actually generate
a full stack trace just creating them, and using them for flow-control
is essentially considered an anti-pattern because of the overhead.

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

Posted by MSCHAEF.COM on December 15th, 2005


In article <43a098c5@news.tulsaconnect.com>,
Jonathan Bartlett <johnnyb@eskimo.com> wrote:
What about C's setjmp/longjmp? I haven't done any performance testing,
but I'd expect it to be a very fast, if dangerous, way of doing non-local
escapes.

-Mike

--
http://www.mschaef.com

Posted by Artie Gold on December 15th, 2005


MSCHAEF.COM wrote:
however as they don't perform all the housekeeping tasks associated with
exceptions (though exceptions can be built no top of them). The cost of
exceptions is typically in the housekeeping.

HTH,
--ag

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"

Posted by Ben Pfaff on December 15th, 2005


Artie Gold <artiegold@austin.rr.com> writes:

I doubt they're really that fast on many implementations. On my
system here, for example, I can see that longjmp() calls
sigprocmask(), which in turn makes a system call. Usually a
system call takes about a microsecond. Not very fast.

(setjmp() is pretty short and simple, though. If you're doing
lots of setjmp() without many calls to longjmp(), that's not
going to be a problem, at least here.)
--
Ben Pfaff
email: blp@cs.stanford.edu
web: http://benpfaff.org

Posted by Jonathan Bartlett on December 15th, 2005


That's almost perfect. Thanks!

Jon
----
Learn to program using Linux assembly language
http://www.cafeshops.com/bartlettpublish.8640017

Posted by Artie Gold on December 16th, 2005


Ben Pfaff wrote:
Fast is such a *relative* term...<geezer>why I remember when....</geezer>

;-)
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
http://www.cafepress.com/goldsays
"If you have nothing to hide, you're not trying!"

Posted by MSCHAEF.COM on December 16th, 2005


In article <40dtjqF1a5lo8U1@individual.net>,
Artie Gold <artiegold@austin.rr.com> wrote:
I decided to measure it (with code I've stuck at the end of this post.

This is using Visual Studio 2003, No optimimzations, on a 1.6GHZ Pentium M (1GB
RAM) I've stepped through it on a per instruction basis to verify it's doing what I
expect.


void doItToIt1(bool doitp)
{
if (doitp)
longjmp(place, 4);
}

void doItToIt(boolean doitp)
{
for(int i = 0; i < COUNT; i++)
{
if (setjmp(place) == 0)
doItToIt1(doitp);
}
}

with the longjmp it takes 175ns per loop iteration, without it,
it takes 147.

The longjmp itself seems to be going through some bookkeeping to
manage an exception stack that I don't claim to understand. It
seems like it might be related to C++ exception handling. Maybe
it's worth trying it on a C-only compiler to see how that would
work.

Sure. They're more of a non local escape. I'd be very wary
of setjmp/longjmp, unwrapped by an abstraction, in production
code.

-Mike


#include "stdafx.h"
#include <windows.h>
#include <assert.h>
#include <setjmp.h>

enum { COUNT = 10000000 };

__int64 frequency = 0;
int performanceCounterUnsupported = FALSE;

double myruntime (void)
{
LARGE_INTEGER temp;
__int64 counterValue;

if ((frequency == 0) && !performanceCounterUnsupported)
{

performanceCounterUnsupported = !QueryPerformanceFrequency(&temp);
frequency = temp.QuadPart;
}

if (performanceCounterUnsupported) {
return ((double)GetTickCount() / 1000.0);
} else {
QueryPerformanceCounter(&temp);
counterValue = temp.QuadPart;

return ((double)counterValue / (double)frequency);
}
}


jmp_buf place;

void doItToIt1(bool doitp)
{
if (doitp)
longjmp(place, 4);
}

void doItToIt(boolean doitp)
{
for(int i = 0; i < COUNT; i++)
{
if (setjmp(place) == 0)
doItToIt1(doitp);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
double before, after;

before = myruntime();
doItToIt(true);
after = myruntime();

printf("with longjmp %f nanoseconds\n", (after - before) / COUNT * 1000000000.0);

before = myruntime();
doItToIt(false);
after = myruntime();

printf("without longjmp %f nanoseconds\n", (after - before) / COUNT * 1000000000.0);

return 0;
}


--
http://www.mschaef.com

Posted by MSCHAEF.COM on December 16th, 2005


In article <87lkymxi4i.fsf@benpfaff.org>,
Ben Pfaff <blp@cs.stanford.edu> wrote:
...
Do you know why it calls sigprocmask? Is it necessary to turn signals
off or on for some reason for this to work?

-Mike
--
http://www.mschaef.com

Posted by Ben Pfaff on December 17th, 2005


mschaef@fnord.io.com (MSCHAEF.COM) writes:

longjmp() can be used to exit a signal handler and re-enable the
signal that invoked it.
--
"I admire him, I frankly confess it; and when his time comes
I shall buy a piece of the rope for a keepsake."
--Mark Twain

Posted by CTips on December 17th, 2005


MSCHAEF.COM wrote:
Try _setjmp/_longjmp instead. Its unspecified whether setjmp/longjmp are
equivalent to sigsetjmp/siglongjmp, and it looks as though in the OP's
environment they are. _setjmp/_longjmp are, however, *guaranteed* to NOT
touch the signal mask, so they should be quicker.


Similar Posts