Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Performance of the Streams 'Read and 'Write
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  17 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Gautier write-only  
View profile  
 More options Oct 30, 10:29 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Thu, 29 Oct 2009 16:29:47 -0700 (PDT)
Local: Fri, Oct 30 2009 10:29 am
Subject: Performance of the Streams 'Read and 'Write
Hello.
I got used to think that I/O was the last spot where our preferred
language was condemned to slowness.
Now consider this. Variant 1 of a buffered I/O:

  type Buffer is array(Natural range <>) of Unsigned_8;

  procedure Read( b: out Buffer ) is
  begin
    Buffer'Read(Stream(f_in), b);
  exception
    when Ada.Streams.Stream_IO.End_Error =>
      null;
      -- Nothing bad, just some garbage in the buffer
      -- after end of compressed code
  end Read;

  procedure Write( b: in Buffer ) is
  begin
    Buffer'Write(Stream(f_out), b);
  end Write;

Bad luck, it is as slow as doing I/O's with single bytes and
Sequential_IO! But if it is slow by receiving/sending a whole buffer,
how to make it faster ? Now someone (in a slightly different context)
came with this (call it variant 2):

  procedure Read( b: out Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      :          Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    for i in First..Last loop
      b(Natural(i)):= Unsigned_8(SE_Buffer(i));
    end loop;
  end Read;

  procedure Write( b: in Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      : constant Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    for i in SE_Buffer'Range loop
      SE_Buffer(i):= Stream_Element(b(Natural(i)));
    end loop;
    Write(Stream(f_out).all, SE_Buffer);
  end Write;

Naively, you would say it is even slower: you do even more by copying
a buffer into another one, right ?
Indeed, not at all, it is *lots* faster (on GNAT and ObjectAda)!
To give an idea, the variant 1 applied to a bzip2 decompressor makes
it 4x slower than the C version, and variant 2 makes it only 7%
slower! With only I/O (like copying a file) you would get an even much
larger difference.

Now, it raises some questions:
Is there maybe a reason in the RM why the 'Read and 'Write have to be
that slow ?
Or are these two compilers lazy when compiling these attributes ?
Should I bug Adacore about that, then ?
Do some other compilers do it better ?
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeffrey R. Carter  
View profile  
 More options Oct 30, 11:39 am
Newsgroups: comp.lang.ada
From: "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org>
Date: Thu, 29 Oct 2009 17:39:39 -0700
Local: Fri, Oct 30 2009 11:39 am
Subject: Re: Performance of the Streams 'Read and 'Write

Gautier write-only wrote:

> Naively, you would say it is even slower: you do even more by copying
> a buffer into another one, right ?
> Indeed, not at all, it is *lots* faster (on GNAT and ObjectAda)!
> To give an idea, the variant 1 applied to a bzip2 decompressor makes
> it 4x slower than the C version, and variant 2 makes it only 7%
> slower! With only I/O (like copying a file) you would get an even much
> larger difference.

And if you overlay the Stream_Element_Array onto the Buffer, thus eliminating
the copying and the stream attribute operations?

--
Jeff Carter
"C's solution to this [variable-sized array parameters] has real
problems, and people who are complaining about safety definitely
have a point."
Dennis Ritchie
25


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Georg Bauhaus  
View profile  
 More options Oct 30, 2:36 pm
Newsgroups: comp.lang.ada
From: Georg Bauhaus <rm-host.bauh...@maps.futureapps.de>
Date: Fri, 30 Oct 2009 04:36:27 +0100
Local: Fri, Oct 30 2009 2:36 pm
Subject: Re: Performance of the Streams 'Read and 'Write
On 10/30/09 12:29 AM, Gautier write-only wrote:

I finally thought that the above procedures are faster than 'Read
or 'Write because the latter are defined in terms of stream elements:
When there is a composite object like b : Buffer and you
'Write it, then for each component of b the corresponding 'Write
is called. This then writes stream elements, probably
calling Stream_IO.Write or some such in the end.
So Write from above appears closer to writing bulk loads
of stream elements than a bulk load of 'Writes can be.

Copying buffers does not matter in comparison to the needs
of I/O (on PCs).


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Oct 30, 7:58 pm
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Fri, 30 Oct 2009 01:58:15 -0700 (PDT)
Local: Fri, Oct 30 2009 7:58 pm
Subject: Re: Performance of the Streams 'Read and 'Write
On 30 Okt., 01:39, "Jeffrey R. Carter"

<spam.jrcarter....@spam.acm.org> wrote:
> And if you overlay the Stream_Element_Array onto the Buffer, thus eliminating
> the copying and the stream attribute operations?

With an Unchecked_conversion ?... Sure, but you cannot guarantee that
the Buffer will be packed the same way as Stream_Element_Array on a
compiler X that you don't know. On that type of project (open-source
compression, no compiler/system dependency) I want to avoid any "dirty
trick" like that.
Anyway, the copying takes almost no time. Note that I do not copy
_and_ use the stream attribute at the same time:
Variant 1 uses the stream attribute on Buffer.
Variant 2 copies into a Stream_Element_Array ans uses the Write
procedure in Ada.Streams.

Gautier


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Oct 30, 8:13 pm
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Fri, 30 Oct 2009 02:13:19 -0700 (PDT)
Local: Fri, Oct 30 2009 8:13 pm
Subject: Re: Performance of the Streams 'Read and 'Write
On 30 Okt., 04:36, Georg Bauhaus <rm-host.bauh...@maps.futureapps.de>:

> I finally thought that the above procedures are faster than 'Read
> or 'Write because the latter are defined in terms of stream elements:
> When there is a composite object like b : Buffer and you
> 'Write it, then for each component of b the corresponding 'Write
> is called. This then writes stream elements, probably
> calling Stream_IO.Write or some such in the end.
> So Write from above appears closer to writing bulk loads
> of stream elements than a bulk load of 'Writes can be.

Sure, it is the safe way: write records field by field, arrays element
by element (that recursively). The compiler avoids problems with non-
packed data. Nothing against that. The general case is well done,
fine. But the compiler could have a look a the type left to the
attribute and in such a case (an array of Unsigned_8, or a String)
say: "Gee! that type Buffer is coincidentally the same as
Stream_Element_Array, then I take the shortcut to generate the code to
write the whole buffer and, this time, not the code to write it
element by element".

> Copying buffers does not matter in comparison to the needs of I/O (on PCs).

Right. Variant 2 works fine, but it is an heavy workaround in terms of
source code. Especially for mixed type I/O with plenty of String'Write
and others, you would not want to put the kind of Variant 2 code all
over the place. It  would be a lot better that compilers are able to
take selectively the shortcut form for the attributes.

Gautier


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Oct 31, 12:40 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Fri, 30 Oct 2009 06:40:27 -0700 (PDT)
Local: Sat, Oct 31 2009 12:40 am
Subject: Re: Performance of the Streams 'Read and 'Write
Here is a test program. I am curious about other results

-- Usage: test_stream_performance <file>
-- Produces two .tmp files that are copies of <file>.
--
-- Example of output with file m.wmv, 2.59 MB, GNAT GPL 2008 / Win32:
--
--  xxx'Write / xxx'Read (Attribute).. 1.925210886 seconds
--  Workaround with SE buffer......... 0.049318559 seconds
--  Factor 39.036235547

--  Buffer size in bits..... 8192
--  SE Buffer size in bits.. 8192

with Ada.Calendar;                      use Ada.Calendar;
with Ada.Text_IO;
with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO;
with Ada.Command_Line;                  use Ada.Command_Line;
with Interfaces;                        use Interfaces;

procedure Test_Stream_Performance is

  f_in, f_out: Ada.Streams.Stream_IO.File_Type;

  buffer_size, SE_buffer_size: Natural:= 0;
  -- To check if buffers could be overlapped (packing)

  type Buffer is array(Natural range <>) of Unsigned_8;

  ------------------------------------------------
  -- 1) Stream attributes - xxx'Read, xxx'Write --
  ------------------------------------------------

  -- Usually we would just have: Buffer'Read(Stream(f_in), b);
  -- Here we care about end of file.

  procedure Read_Attribute( b: out Buffer; last_read: out Natural ) is
    idx: constant Positive_Count:= Index(f_in);
    siz: constant Positive_Count:= Size(f_in);
  begin
    if End_Of_File(f_in) then
      last_read:= b'First-1;
    else
      last_read:= Natural'Min(b'First+Natural(siz-idx),b'Last);
      Buffer'Read(Stream(f_in), b(b'First .. last_read));
    end if;
  end Read_Attribute;

  procedure Write_Attribute( b: in Buffer ) is
  begin
    if buffer_size = 0 then
      buffer_size:= b'size;
    end if;
    Buffer'Write(Stream(f_out), b);
  end Write_Attribute;

  --------------------------------------------
  -- 2) The Stream_Element_Array workaround --
  --------------------------------------------

  procedure Read_SE( b: out Buffer; last_read: out Natural ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      :          Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    for i in First..Last loop
      b(Natural(i)):= Unsigned_8(SE_Buffer(i));
    end loop;
    last_read:= Natural(last);
  end Read_SE;

  procedure Write_SE( b: in Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      : constant Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    if SE_buffer_size = 0 then
      SE_buffer_size:= SE_Buffer'size;
    end if;
    for i in SE_Buffer'Range loop
      SE_Buffer(i):= Stream_Element(b(Natural(i)));
    end loop;
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE;

  name : constant String:= Argument(1);

  generic
    label: String;
    with procedure Read( b: out Buffer; last_read: out Natural  );
    with procedure Write( b: in Buffer  );
  procedure Test;

  procedure Test is
    b: Buffer(1..1024);
    l: Natural;
  begin
    Open(f_in, In_File, name);
    Create(f_out, Out_File, name & "_$$$_" & label & ".tmp");
    while not End_of_File(f_in) loop
      Read(b,l);
      Write(b(1..l));
    end loop;
    Close(f_out);
    Close(f_in);
  end;

  procedure Test_Attribute is new Test("Attribute", Read_Attribute,
Write_Attribute);
  procedure Test_SE is new Test("SE", Read_SE, Write_SE);

  T0, T1, T2: Time;

  use Ada.Text_IO;

begin
  T0:= Clock;
  Test_Attribute;
  T1:= Clock;
  Test_SE;
  T2:= Clock;
  Put_Line("xxx'Write / xxx'Read (Attribute).." & Duration'Image(T1-
T0) & " seconds");
  Put_Line("Workaround with SE buffer........." & Duration'Image(T2-
T1) & " seconds");
  Put_Line("Factor" & Duration'Image((T1-T0)/(T2-T1)));
  New_Line;
  Put_Line("Buffer size in bits....." & Integer'Image(buffer_size));
  Put_Line("SE Buffer size in bits.." & Integer'Image
(SE_buffer_size));
end;


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeffrey R. Carter  
View profile  
 More options Oct 31, 6:12 am
Newsgroups: comp.lang.ada
From: "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org>
Date: Fri, 30 Oct 2009 12:12:18 -0700
Local: Sat, Oct 31 2009 6:12 am
Subject: Re: Performance of the Streams 'Read and 'Write

Gautier write-only wrote:
> On 30 Okt., 01:39, "Jeffrey R. Carter"
> <spam.jrcarter....@spam.acm.org> wrote:

>> And if you overlay the Stream_Element_Array onto the Buffer, thus eliminating
>> the copying and the stream attribute operations?

> With an Unchecked_conversion ?

No, that still does a copy.

Type Buffer, as a simple array of bytes, should have Buffer'Component_Size =
Unsigned_8'Size by default; but you can specify it if you're paranoid. If you're
really paranoid, you can add a test that Unsigned_8'Size = Stream_Element'Size,
which you seem to be assuming. Then

procedure Put (B : in Buffer) is -- Terrible naming scheme.
    subtype Buffer_Stream is Stream_Element_Array (1 .. B'Length);

    S : Buffer_Stream;
    for S'Address use B'Address;
    pragma Import (Ada, S);
begin -- Put
    Write (S);
end Put;

--
Jeff Carter
"I spun around, and there I was, face to face with a
six-year-old kid. Well, I just threw my guns down and
walked away. Little bastard shot me in the ass."
Blazing Saddles
40


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 1, 10:46 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Sat, 31 Oct 2009 16:46:32 -0700 (PDT)
Local: Sun, Nov 1 2009 10:46 am
Subject: Re: Performance of the Streams 'Read and 'Write
On 30 oct, 20:12, "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org>
wrote:

> >> And if you overlay the Stream_Element_Array onto the Buffer, thus eliminating
> >> the copying and the stream attribute operations?
>     for S'Address use B'Address;

Bingo!

xxx'Write / xxx'Read (Stream attributes)................ 14.717895000
seconds
Workaround with Stream_Element_Array buffer and copy.... 0.435756000
seconds
Workaround with Stream_Element_Array buffer and overlay. 0.211830000
seconds
Factor (Copy)    33.775541816
Factor (Overlay) 69.479747911

This on a Linux 32 bit netbook, with a 32 MB file; GNAT GPL 2009, -
gnatp -O2.
So my "almost no time" assumption about the buffer copy was definitely
to be understood as "compared to the attribute version"...
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 2, 8:38 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Sun, 1 Nov 2009 13:38:44 -0800 (PST)
Local: Mon, Nov 2 2009 8:38 am
Subject: Re: Performance of the Streams 'Read and 'Write
Jeffrey R. Carter:

> If you're
> really paranoid, you can add a test that Unsigned_8'Size = Stream_Element'Size,
> which you seem to be assuming.

Yet a bit more paranoid: checking the size of arrays!

  workaround_possible: Boolean;

  procedure Check_workaround is
    test_a: constant Byte_Buffer(1..10):= (others => 0);
    test_b: constant Ada.Streams.Stream_Element_Array(1..10):= (others
=> 0);
  begin
    workaround_possible:= test_a'Size = test_b'Size;
  end Check_workaround;

It's the code I've put into Zip-Ada - big success!
:-)
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Randy Brukardt  
View profile  
 More options Nov 3, 8:32 am
Newsgroups: comp.lang.ada
From: "Randy Brukardt" <ra...@rrsoftware.com>
Date: Mon, 2 Nov 2009 15:32:51 -0600
Local: Tues, Nov 3 2009 8:32 am
Subject: Re: Performance of the Streams 'Read and 'Write
"Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org> wrote in message
news:hcfdpo$p62$1@news.tornevall.net...

> Gautier write-only wrote:
>> On 30 Okt., 01:39, "Jeffrey R. Carter"
>> <spam.jrcarter....@spam.acm.org> wrote:

>>> And if you overlay the Stream_Element_Array onto the Buffer, thus
>>> eliminating
>>> the copying and the stream attribute operations?

>> With an Unchecked_conversion ?

> No, that still does a copy.

It doesn't have to, there is a permission to avoid copying in 13.9(12). So
it depends on what the compiler is able to do optimization-wise.

                                           Randy.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Randy Brukardt  
View profile  
 More options Nov 3, 8:37 am
Newsgroups: comp.lang.ada
From: "Randy Brukardt" <ra...@rrsoftware.com>
Date: Mon, 2 Nov 2009 15:37:48 -0600
Local: Tues, Nov 3 2009 8:37 am
Subject: Re: Performance of the Streams 'Read and 'Write
"Gautier write-only" <gautier_niou...@hotmail.com> wrote in message

news:715d78f4-9b01-4598-88c1-6fc202983bae@p35g2000yqh.googlegroups.com...

IMHO, Ada compilers should do that. (There's specifically a permission to do
this optimization in Ada 2005: 13.13.2(56/2).) That's an intergral part of
the stream attribute implementation on Janus/Ada. (Disclaimer: the entire
stream attribute implementation on Janus/Ada doesn't work right, quite
probably because it is too complicated. So perhaps there is a reason that
other Ada compilers don't do that. :-) Note, however, that it is pretty rare
that you could actually do that (only about 15% of the composite types I've
seen in Janus/Ada would qualify). So I'm not surprised that implementers
have left that capability out in favor of things that happen more often.

                             Randy.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 3, 9:16 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Mon, 2 Nov 2009 14:16:30 -0800 (PST)
Local: Tues, Nov 3 2009 9:16 am
Subject: Re: Performance of the Streams 'Read and 'Write
On 2 nov, 22:37, "Randy Brukardt" <ra...@rrsoftware.com> wrote:

> IMHO, Ada compilers should do that. (There's specifically a permission to do
> this optimization in Ada 2005: 13.13.2(56/2).)

Excellent news!

> That's an intergral part of
> the stream attribute implementation on Janus/Ada. (Disclaimer: the entire
> stream attribute implementation on Janus/Ada doesn't work right, quite
> probably because it is too complicated. So perhaps there is a reason that
> other Ada compilers don't do that. :-) Note, however, that it is pretty rare
> that you could actually do that (only about 15% of the composite types I've
> seen in Janus/Ada would qualify).

Sure - but imagine that these 15% might transport 95% of the
information. It could happen, couldn't it ?
And if type T qualifies, a record type R with fields of types T,U,V (U
and V not qualifying) will be also transmitted faster, an array of R
will also go faster, and so on...

> So I'm not surprised that implementers
> have left that capability out in favor of things that happen more often.

I am not surprised either...

Gautier


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 3, 9:19 am
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Mon, 2 Nov 2009 14:19:48 -0800 (PST)
Local: Tues, Nov 3 2009 9:19 am
Subject: Re: Performance of the Streams 'Read and 'Write
Here is the ultimate test ;-), with Jeff's overlay idea and the
unchecked_conversion as well.
G.

-- Usage: test_stream_performance <big_file>
-- Produces .tmp files that are copies of <big_file>.
--
-- Example of output with GNAT GPL 2008 / Win32:
--
--  xxx'Write / xxx'Read (Stream attributes)......... 9.282530042
seconds
--  Workarounds with Stream_Element_Array buffer:
--    copy........................................... 0.444120412
seconds
--    overlay (read), unchecked_conversion (write)... 0.156874407
seconds
--    overlay........................................ 0.150155676
seconds
--  Factor (Copy)    20.900930898
--  Factor (Overlay) 61.819374993

--  Buffer size in bits..... 8192
--  SE Buffer size in bits.. 8192

--  File size in megabytes..... 2.46367E+01

with Ada.Calendar;                      use Ada.Calendar;
with Ada.Text_IO;
with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO;
with Ada.Command_Line;                  use Ada.Command_Line;
with Ada.Unchecked_Conversion;
with Interfaces;                        use Interfaces;

procedure Test_Stream_Performance is

  f_in, f_out: Ada.Streams.Stream_IO.File_Type;

  buffer_size, SE_buffer_size: Natural:= 0;
  -- To check if buffers are binary compatible (same packing)

  type Buffer is array(Natural range <>) of Unsigned_8;

  ------------------------------------------------
  -- 1) Stream attributes - xxx'Read, xxx'Write --
  ------------------------------------------------

  -- NB: usually we would just have: Buffer'Read(Stream(f_in), b);
  -- Here we care about end of file.
  --
  procedure Read_Attribute( b: out Buffer; last_read: out Natural ) is
    idx: constant Positive_Count:= Index(f_in);
    siz: constant Positive_Count:= Size(f_in);
  begin
    if End_Of_File(f_in) then
      last_read:= b'First-1;
    else
      last_read:= Natural'Min(b'First+Natural(siz-idx),b'Last);
      Buffer'Read(Stream(f_in), b(b'First .. last_read));
    end if;
  end Read_Attribute;

  procedure Write_Attribute( b: in Buffer ) is
  begin
    if buffer_size = 0 then
      buffer_size:= b'size; -- just for stats
    end if;
    Buffer'Write(Stream(f_out), b);
  end Write_Attribute;

  ---------------------------------------------
  -- 2) The Stream_Element_Array workarounds --
  ---------------------------------------------

  procedure Read_SE_Copy( b: out Buffer; last_read: out Natural ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      :          Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    for i in First..Last loop
      b(Natural(i)):= Unsigned_8(SE_Buffer(i));
    end loop;
    last_read:= Natural(last);
  end Read_SE_Copy;

  procedure Write_SE_Copy( b: in Buffer ) is
    use Ada.Streams;
    First     : constant Stream_Element_Offset:= Stream_Element_Offset
(b'First);
    Last      : constant Stream_Element_Offset:= Stream_Element_Offset
(b'Last);
    SE_Buffer : Stream_Element_Array (First..Last);
  begin
    if SE_buffer_size = 0 then
      SE_buffer_size:= SE_Buffer'size; -- just for stats
    end if;
    for i in SE_Buffer'Range loop
      SE_Buffer(i):= Stream_Element(b(Natural(i)));
    end loop;
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE_Copy;

  -- Overlay idea by Jeff Carter

  procedure Read_SE_Overlay( b: out Buffer; last_read: out Natural )
is
    use Ada.Streams;
    Last: Stream_Element_Offset;
    SE_Buffer : Stream_Element_Array (1..b'Length);
    for SE_Buffer'Address use b'Address;
  begin
    Read(Stream(f_in).all, SE_Buffer, Last);
    last_read:= b'First + Natural(Last) - 1;
  end Read_SE_Overlay;

  procedure Write_SE_Overlay( b: in Buffer ) is
    use Ada.Streams;
    SE_Buffer : Stream_Element_Array (1..b'Length);
    for SE_Buffer'Address use b'Address;
  begin
    Write(Stream(f_out).all, SE_Buffer);
  end Write_SE_Overlay;

  -- Using Unchecked_Conversion

  procedure Write_SE_UC( b: in Buffer ) is
    subtype My_SEA is Ada.Streams.Stream_Element_Array(1..b'Length);
    function To_SEA is new Ada.Unchecked_Conversion(Buffer, My_SEA);
    use Ada.Streams;
  begin
    Write(Stream(f_out).all, To_SEA(b));
  end Write_SE_UC;

  ----------
  -- Test --
  ----------

  function name return String is
  begin
    return Argument(1);
  end;

  generic
    label: String;
    with procedure Read( b: out Buffer; last_read: out Natural  );
    with procedure Write( b: in Buffer  );
  procedure Test;

  procedure Test is
    b: Buffer(1..1024);
    l: Natural;
  begin
    Open(f_in, In_File, name);
    Create(f_out, Out_File, name & "_$$$_" & label & ".tmp");
    while not End_of_File(f_in) loop
      Read(b,l);
      Write(b(1..l));
    end loop;
    Close(f_out);
    Close(f_in);
  end;

  procedure Test_Attribute is new Test("Attribute", Read_Attribute,
Write_Attribute);
  procedure Test_SE_Copy is new Test("SE_Copy", Read_SE_Copy,
Write_SE_Copy);
  procedure Test_SE_Overlay is new Test("SE_Overlay", Read_SE_Overlay,
Write_SE_Overlay);
  procedure Test_SE_UC is new Test("SE_UC", Read_SE_Overlay,
Write_SE_UC);

  T0, T1, T2, T3, T4: Time;

  use Ada.Text_IO;

begin
  if Argument_Count=0 then
    Put_Line(" Usage: test_stream_performance <big_file>");
    Put_Line(" Produces .tmp files that are copies of <big_file>.");
    return;
  end if;
  T0:= Clock;
  Test_Attribute;
  T1:= Clock;
  Test_SE_Copy;
  T2:= Clock;
  Test_SE_Overlay;
  T3:= Clock;
  Test_SE_UC;
  T4:= Clock;
  Put_Line("xxx'Write / xxx'Read (Stream attributes)........." &
Duration'Image(T1-T0) & " seconds");
  Put_Line("Workarounds with Stream_Element_Array buffer:");
  Put_Line("  copy..........................................." &
Duration'Image(T2-T1) & " seconds");
  Put_Line("  overlay (read), unchecked_conversion (write)..." &
Duration'Image(T4-T3) & " seconds");
  Put_Line("  overlay........................................" &
Duration'Image(T3-T2) & " seconds");
  Put_Line("Factor (Copy)   " & Duration'Image((T1-T0)/(T2-T1)));
  Put_Line("Factor (Overlay)" & Duration'Image((T1-T0)/(T3-T2)));
  New_Line;
  Put_Line("Buffer size in bits....." & Integer'Image(buffer_size));
  Put_Line("SE Buffer size in bits.." & Integer'Image
(SE_buffer_size));
  New_Line;
  Open(f_in, In_File, name);
  Put_Line("File size in megabytes....." & Float'Image(Float(Size
(f_in))/(1024.0*1024.0)));
  Close(f_in);
end;


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 17, 11:57 pm
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Tue, 17 Nov 2009 04:57:26 -0800 (PST)
Local: Tues, Nov 17 2009 11:57 pm
Subject: Re: Performance of the Streams 'Read and 'Write
Hello,
I have an idea about how to patch GNAT on this.
Indeed, there is already a fast Stream exchangein GNAT, only for the
{Wide_}String types.
So, at the end of Find_Stream_Subprogram, exp_attr.adb, I would add
something like

if Is_Array_Type(Typ) and then
  Is_Bit_Packed_Array (Typ) and then
  Component_Size (Typ) = 8 and then
then
  Comp_Typ:= Component_Type (Typ);
  if Is_Modular_Integer_Type(Comp_Typ) and then
    [modulus ??] (Comp_Typ) = 2**8
  then
    [ go ahead with some unchecked conversion to String ]
    return [the right thing];
  end if;
end if;

Now, I have no experience with building GNAT, from the GCC tree.
Would someone like to help ?
Or is it easy to on Windows (currently, no Linux available on my
side) ?
TIA
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ludovic Brenta  
View profile  
 More options Nov 18, 12:26 am
Newsgroups: comp.lang.ada
From: Ludovic Brenta <ludo...@ludovic-brenta.org>
Date: Tue, 17 Nov 2009 05:26:12 -0800 (PST)
Local: Wed, Nov 18 2009 12:26 am
Subject: Re: Performance of the Streams 'Read and 'Write
Gautier wrote on comp.lang.ada:

> Now, I have no experience with building GNAT, from the GCC tree.
> Would someone like to help ?
> Or is it easy to on Windows (currently, no Linux available on my
> side) ?
> TIA

http://goodbye-microsoft.com/ :)

*ducks and hides*

--
Ludovic Brenta.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Discussion subject changed to "Building GNAT on Windows (Was: Re: Performance of the Streams 'Read and 'Write)" by Tero Koskinen
Tero Koskinen  
View profile  
 More options Nov 18, 7:19 am
Newsgroups: comp.lang.ada
From: Tero Koskinen <tero.koski...@iki.fi>
Date: Tue, 17 Nov 2009 22:19:34 +0200
Local: Wed, Nov 18 2009 7:19 am
Subject: Building GNAT on Windows (Was: Re: Performance of the Streams 'Read and 'Write)
On Tue, 17 Nov 2009 04:57:26 -0800 (PST) Gautier write-only wrote:

> Now, I have no experience with building GNAT, from the GCC tree.
> Would someone like to help ?
> Or is it easy to on Windows (currently, no Linux available on my
> side) ?

Building GNAT on Windows should work as long as you have binary version
of GNAT already installed.

Search for cygwin or mingw. Also, look at avr-ada and gnuada projects
at sourceforge.net for examples.

Some links:
http://sourceforge.net/apps/mediawiki/avr-ada/index.php?title=BuildSc...

http://gnuada.sourceforge.net/

http://en.wikibooks.org/wiki/Ada_Programming/Installing

http://ada.krischik.com/index.php/Articles/CompileGNATGPL?from=Articl...

--
Tero Koskinen - http://iki.fi/tero.koskinen/


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gautier write-only  
View profile  
 More options Nov 18, 9:55 pm
Newsgroups: comp.lang.ada
From: Gautier write-only <gautier_niou...@hotmail.com>
Date: Wed, 18 Nov 2009 02:55:34 -0800 (PST)
Local: Wed, Nov 18 2009 9:55 pm
Subject: Re: Building GNAT on Windows (Was: Re: Performance of the Streams 'Read and 'Write)
Thanks Tero, the links are very useful and informative.
If it sorts out to be too complicated for me, at least it gives me
ideas on how to find motivated people...
For example AVR-Ada might benefit a lot from a speedup of any
Byte_Array'Read / 'Write :-).
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google