comp.lang.ada
 help / color / mirror / Atom feed
From: Gautier write-only <gautier_niouzes@hotmail.com>
Subject: Re: Performance of the Streams 'Read and 'Write
Date: Mon, 2 Nov 2009 14:19:48 -0800 (PST)
Date: 2009-11-02T14:19:48-08:00	[thread overview]
Message-ID: <be57865e-761a-4dc1-b17e-a3e25068fbcc@a31g2000yqn.googlegroups.com> (raw)
In-Reply-To: 53b1e21a-1659-462c-bf7f-de8f04b849e1@37g2000yqm.googlegroups.com

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	other threads:[~2009-11-02 22:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-29 23:29 Performance of the Streams 'Read and 'Write Gautier write-only
2009-10-30  0:39 ` Jeffrey R. Carter
2009-10-30  8:58   ` Gautier write-only
2009-10-30 19:12     ` Jeffrey R. Carter
2009-10-31 23:46       ` Gautier write-only
2009-11-01 21:38       ` Gautier write-only
2009-11-02 21:32       ` Randy Brukardt
2009-10-30  3:36 ` Georg Bauhaus
2009-10-30  9:13   ` Gautier write-only
2009-11-02 21:37     ` Randy Brukardt
2009-11-02 22:16       ` Gautier write-only
2009-10-30 13:40 ` Gautier write-only
2009-11-02 22:19   ` Gautier write-only [this message]
2009-11-17 12:57 ` Gautier write-only
2009-11-17 13:26   ` Ludovic Brenta
2009-11-17 20:19   ` Building GNAT on Windows (Was: Re: Performance of the Streams 'Read and 'Write) Tero Koskinen
2009-11-18 10:55     ` Gautier write-only
2009-11-26 13:23   ` Performance of the Streams 'Read and 'Write Gautier write-only
replies disabled

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