comp.lang.ada
 help / color / mirror / Atom feed
* Exception handling overhead?
@ 2009-04-24 11:52 Peter C. Chapin
  2009-04-24 12:06 ` Ludovic Brenta
  2009-04-24 14:06 ` anon
  0 siblings, 2 replies; 6+ messages in thread
From: Peter C. Chapin @ 2009-04-24 11:52 UTC (permalink / raw)


Hello!

I'm creating a type intended to represent lines of editable text. It 
will provide some specialized services and is not intended to be a 
general purpose string type. At the moment I'm wrapping the type 
Ada.Strings.Unbounded.Unbounded_String (I'm really using Wide_Strings, 
but I don't think that's important right now). I may want to change that 
underlying implementation in the future so I don't want to directly 
expose my current choice to my clients. Thus I'm providing some 
subprograms that do some minor things and then just forward to 
subprograms in Ada.Strings.Unbounded.

My question is about exceptions. To avoid exposing my implementation 
choice and to give me more control in the long run I've defined my own 
exception for (as an example) an out of bounds access:

Bad_Index : exception;

Naturally I want to raise this exception if the client tries to access a 
character not in my buffer. This leads to two possibilities.

function Element(B : Buffer; Index : Positive) return Character is
begin
  if Index > Ada.Strings.Unbounded.Length(B.Internal_String) then
    raise Bad_Index;
  end if;
  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
end Element;

This entails two checks on the index value: the one I'm doing and the 
one being done inside Ada.Strings.Unbounded.Element. Another approach is

function Element(B : Buffer; Index : Positive) return Character is
begin
  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
exception
  when Ada.Strings.Index_Error =>
    raise Bad_Index;
end Element;

This lets the check exist in only one place but it invokes the machinery 
of exception handling.

Now I know that in C++ there are implementation methods that allow zero 
execution time overhead in the case when an exception is not thrown (at 
the expense of increasing executable size and making thrown exceptions 
slower). Compilers are not required to use such methods, of course, but 
I know of at least one that does... or that can if the right options are 
selected. I'm wondering about how this might work in Ada. Does Ada admit 
such implementation methods? If so, do compilers commonly use them? From 
a raw performance point of view which of the two approaches above would 
be "better?"

For the record... I understand that in my application it probably 
doesn't matter much either way. I also understand that the answer is 
likely to be very compiler specific. This is mostly a question of 
academic interest.

Thanks!

Peter



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Exception handling overhead?
  2009-04-24 11:52 Exception handling overhead? Peter C. Chapin
@ 2009-04-24 12:06 ` Ludovic Brenta
  2009-04-24 12:42   ` Dmitry A. Kazakov
  2009-04-25 11:58   ` Peter C. Chapin
  2009-04-24 14:06 ` anon
  1 sibling, 2 replies; 6+ messages in thread
From: Ludovic Brenta @ 2009-04-24 12:06 UTC (permalink / raw)


On Apr 24, 1:52 pm, "Peter C. Chapin" <pcc482...@gmail.com> wrote:
> Hello!
>
> I'm creating a type intended to represent lines of editable text. It
> will provide some specialized services and is not intended to be a
> general purpose string type. At the moment I'm wrapping the type
> Ada.Strings.Unbounded.Unbounded_String (I'm really using Wide_Strings,
> but I don't think that's important right now). I may want to change that
> underlying implementation in the future so I don't want to directly
> expose my current choice to my clients. Thus I'm providing some
> subprograms that do some minor things and then just forward to
> subprograms in Ada.Strings.Unbounded.
>
> My question is about exceptions. To avoid exposing my implementation
> choice and to give me more control in the long run I've defined my own
> exception for (as an example) an out of bounds access:
>
> Bad_Index : exception;
>
> Naturally I want to raise this exception if the client tries to access a
> character not in my buffer. This leads to two possibilities.
>
> function Element(B : Buffer; Index : Positive) return Character is
> begin
>   if Index > Ada.Strings.Unbounded.Length(B.Internal_String) then
>     raise Bad_Index;
>   end if;
>   return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
> end Element;
>
> This entails two checks on the index value: the one I'm doing and the
> one being done inside Ada.Strings.Unbounded.Element. Another approach is
>
> function Element(B : Buffer; Index : Positive) return Character is
> begin
>   return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
> exception
>   when Ada.Strings.Index_Error =>
>     raise Bad_Index;
> end Element;
>
> This lets the check exist in only one place but it invokes the machinery
> of exception handling.
>
> Now I know that in C++ there are implementation methods that allow zero
> execution time overhead in the case when an exception is not thrown (at
> the expense of increasing executable size and making thrown exceptions
> slower). Compilers are not required to use such methods, of course, but
> I know of at least one that does... or that can if the right options are
> selected. I'm wondering about how this might work in Ada. Does Ada admit
> such implementation methods? If so, do compilers commonly use them? From
> a raw performance point of view which of the two approaches above would
> be "better?"
>
> For the record... I understand that in my application it probably
> doesn't matter much either way. I also understand that the answer is
> likely to be very compiler specific. This is mostly a question of
> academic interest.
>
> Thanks!
>
> Peter

GNAT provides two exception handling mechanisms: zero-cost and setjump/
longjump. "Zero-cost" really means zero _distributed_ cost, i.e. you
incur a cost only when raising an exception, as you describe. The
older setjump/longjump mechanism costs some execution time and memory
whether you raise exceptions or not. It is possible to select either
mechanism when compiling your program. For some details, see the short
mailing list thread starting at [1].

[1] http://gcc.gnu.org/ml/gcc/2006-10/msg00270.html

Of course, this is compiler-specific.

HTH

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Exception handling overhead?
  2009-04-24 12:06 ` Ludovic Brenta
@ 2009-04-24 12:42   ` Dmitry A. Kazakov
  2009-04-25 11:58   ` Peter C. Chapin
  1 sibling, 0 replies; 6+ messages in thread
From: Dmitry A. Kazakov @ 2009-04-24 12:42 UTC (permalink / raw)


On Fri, 24 Apr 2009 05:06:30 -0700 (PDT), Ludovic Brenta wrote:

> GNAT provides two exception handling mechanisms: zero-cost and setjump/
> longjump. "Zero-cost" really means zero _distributed_ cost, i.e. you
> incur a cost only when raising an exception, as you describe. The
> older setjump/longjump mechanism costs some execution time and memory
> whether you raise exceptions or not. It is possible to select either
> mechanism when compiling your program. For some details, see the short
> mailing list thread starting at [1].
> 
> [1] http://gcc.gnu.org/ml/gcc/2006-10/msg00270.html
> 
> Of course, this is compiler-specific.

Plus, I guess that whatever distributed overhead exceptions might have, it
should be negligible comparing to the overhead of unbounded strings.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Exception handling overhead?
  2009-04-24 11:52 Exception handling overhead? Peter C. Chapin
  2009-04-24 12:06 ` Ludovic Brenta
@ 2009-04-24 14:06 ` anon
  2009-04-24 15:48   ` Georg Bauhaus
  1 sibling, 1 reply; 6+ messages in thread
From: anon @ 2009-04-24 14:06 UTC (permalink / raw)


You must disable the compiler default Range checking, like:


  function Element( B : Buffer; Index : Positive ) return Character is

    begin
      declare
        -- Temporary disable system checks

        pragma Suppress ( Range_Check ) ;
      begin
        if Index > Ada.Strings.Unbounded.Length ( B.Internal_String ) then
          raise Bad_Index ;
        end if ;
      end ;
    return Ada.Strings.Unbounded.Element ( B.Internal_String, Index ) ;
  end Element ;


In <Xns9BF75019363FApcc482719gmailcom@198.186.192.137>, "Peter C. Chapin" <pcc482719@gmail.com> writes:
>Hello!
>
>I'm creating a type intended to represent lines of editable text. It 
>will provide some specialized services and is not intended to be a 
>general purpose string type. At the moment I'm wrapping the type 
>Ada.Strings.Unbounded.Unbounded_String (I'm really using Wide_Strings, 
>but I don't think that's important right now). I may want to change that 
>underlying implementation in the future so I don't want to directly 
>expose my current choice to my clients. Thus I'm providing some 
>subprograms that do some minor things and then just forward to 
>subprograms in Ada.Strings.Unbounded.
>
>My question is about exceptions. To avoid exposing my implementation 
>choice and to give me more control in the long run I've defined my own 
>exception for (as an example) an out of bounds access:
>
>Bad_Index : exception;
>
>Naturally I want to raise this exception if the client tries to access a 
>character not in my buffer. This leads to two possibilities.
>
>function Element(B : Buffer; Index : Positive) return Character is
>begin
>  if Index > Ada.Strings.Unbounded.Length(B.Internal_String) then
>    raise Bad_Index;
>  end if;
>  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
>end Element;
>
>This entails two checks on the index value: the one I'm doing and the 
>one being done inside Ada.Strings.Unbounded.Element. Another approach is
>
>function Element(B : Buffer; Index : Positive) return Character is
>begin
>  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
>exception
>  when Ada.Strings.Index_Error =>
>    raise Bad_Index;
>end Element;
>
>This lets the check exist in only one place but it invokes the machinery 
>of exception handling.
>
>Now I know that in C++ there are implementation methods that allow zero 
>execution time overhead in the case when an exception is not thrown (at 
>the expense of increasing executable size and making thrown exceptions 
>slower). Compilers are not required to use such methods, of course, but 
>I know of at least one that does... or that can if the right options are 
>selected. I'm wondering about how this might work in Ada. Does Ada admit 
>such implementation methods? If so, do compilers commonly use them? From 
>a raw performance point of view which of the two approaches above would 
>be "better?"
>
>For the record... I understand that in my application it probably 
>doesn't matter much either way. I also understand that the answer is 
>likely to be very compiler specific. This is mostly a question of 
>academic interest.
>
>Thanks!
>
>Peter




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Exception handling overhead?
  2009-04-24 14:06 ` anon
@ 2009-04-24 15:48   ` Georg Bauhaus
  0 siblings, 0 replies; 6+ messages in thread
From: Georg Bauhaus @ 2009-04-24 15:48 UTC (permalink / raw)


anon schrieb:
> You must disable the compiler default Range checking, like:

Or Index_Check.  However, this only gives an implementation
permission to omit certain checks. So I wonder whether
 pragma Suppress ( *_Check )
will have an effect on the library code, or whether the library will
have to be recompiled, and then, whether recompilation of the
library will still produce correct code.



> 
>   function Element( B : Buffer; Index : Positive ) return Character is
> 
>     begin
>       declare
>         -- Temporary disable system checks
> 
>         pragma Suppress ( Range_Check ) ;
>       begin
>         if Index > Ada.Strings.Unbounded.Length ( B.Internal_String ) then
>           raise Bad_Index ;
>         end if ;
>       end ;
>     return Ada.Strings.Unbounded.Element ( B.Internal_String, Index ) ;
>   end Element ;
> 
> 
> In <Xns9BF75019363FApcc482719gmailcom@198.186.192.137>, "Peter C. Chapin" <pcc482719@gmail.com> writes:
>> Hello!
>>
>> I'm creating a type intended to represent lines of editable text. It 
>> will provide some specialized services and is not intended to be a 
>> general purpose string type. At the moment I'm wrapping the type 
>> Ada.Strings.Unbounded.Unbounded_String (I'm really using Wide_Strings, 
>> but I don't think that's important right now). I may want to change that 
>> underlying implementation in the future so I don't want to directly 
>> expose my current choice to my clients. Thus I'm providing some 
>> subprograms that do some minor things and then just forward to 
>> subprograms in Ada.Strings.Unbounded.
>>
>> My question is about exceptions. To avoid exposing my implementation 
>> choice and to give me more control in the long run I've defined my own 
>> exception for (as an example) an out of bounds access:
>>
>> Bad_Index : exception;
>>
>> Naturally I want to raise this exception if the client tries to access a 
>> character not in my buffer. This leads to two possibilities.
>>
>> function Element(B : Buffer; Index : Positive) return Character is
>> begin
>>  if Index > Ada.Strings.Unbounded.Length(B.Internal_String) then
>>    raise Bad_Index;
>>  end if;
>>  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
>> end Element;
>>
>> This entails two checks on the index value: the one I'm doing and the 
>> one being done inside Ada.Strings.Unbounded.Element. Another approach is
>>
>> function Element(B : Buffer; Index : Positive) return Character is
>> begin
>>  return Ada.Strings.Unbounded.Element(B.Internal_String, Index);
>> exception
>>  when Ada.Strings.Index_Error =>
>>    raise Bad_Index;
>> end Element;
>>
>> This lets the check exist in only one place but it invokes the machinery 
>> of exception handling.
>>
>> Now I know that in C++ there are implementation methods that allow zero 
>> execution time overhead in the case when an exception is not thrown (at 
>> the expense of increasing executable size and making thrown exceptions 
>> slower). Compilers are not required to use such methods, of course, but 
>> I know of at least one that does... or that can if the right options are 
>> selected. I'm wondering about how this might work in Ada. Does Ada admit 
>> such implementation methods? If so, do compilers commonly use them? From 
>> a raw performance point of view which of the two approaches above would 
>> be "better?"
>>
>> For the record... I understand that in my application it probably 
>> doesn't matter much either way. I also understand that the answer is 
>> likely to be very compiler specific. This is mostly a question of 
>> academic interest.
>>
>> Thanks!
>>
>> Peter
> 


-- 
--
Georg Bauhaus
Y A Time Drain  http://www.9toX.de



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Exception handling overhead?
  2009-04-24 12:06 ` Ludovic Brenta
  2009-04-24 12:42   ` Dmitry A. Kazakov
@ 2009-04-25 11:58   ` Peter C. Chapin
  1 sibling, 0 replies; 6+ messages in thread
From: Peter C. Chapin @ 2009-04-25 11:58 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> wrote in news:9faab480-850c-
4ec5-b05e-8daec0301928@x5g2000yqk.googlegroups.com:

> GNAT provides two exception handling mechanisms: zero-cost and setjump/
> longjump. "Zero-cost" really means zero _distributed_ cost, i.e. you
> incur a cost only when raising an exception, as you describe. The
> older setjump/longjump mechanism costs some execution time and memory
> whether you raise exceptions or not. It is possible to select either
> mechanism when compiling your program.

Thanks! I'll check it out. It sounds interesting.

Peter



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-04-25 11:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-24 11:52 Exception handling overhead? Peter C. Chapin
2009-04-24 12:06 ` Ludovic Brenta
2009-04-24 12:42   ` Dmitry A. Kazakov
2009-04-25 11:58   ` Peter C. Chapin
2009-04-24 14:06 ` anon
2009-04-24 15:48   ` Georg Bauhaus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox