From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=BAYES_00,PDS_OTHER_BAD_TLD autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,9c86eb13dd395066 X-Google-Attributes: gid103376,public From: jmatthews@nova.wright.edu (Dr. John B. Matthews) Subject: Re: CRC in Ada? Date: 1997/03/09 Message-ID: <1997Mar9.011827@nova.wright.edu> X-Deja-AN: 224125789 References: <1997Mar2.220652@nova.wright.edu> <1997Mar5.083233.1@eisner> <1997Mar5.131846.1@eisner> Organization: Wright State University Newsgroups: comp.lang.ada Date: 1997-03-09T00:00:00+00:00 List-Id: In article , dewar@merv.cs.nyu.edu (Robert Dewar) writes: > More likely to be efficient is using Read and Write directly on > buffers of stream elements. Yes. In the code below I tried to compare Sequential_IO to Stream_IO for the two extremes of one-at-a-time vs all-at-once (imagining a buffered approach to fall between). In the one-at-a-time procedures, I assumed knowledge of the file's length instead of calling the relevant End_Of_File predicate; in the all-at-once procedures, I looped through the resulting buffer. For Sequential_IO, all-at-once is clearly faster than one-at-a-time. Stream_IO is more interesting: In Stream_All1, String'Read is actually slower than looping with Character'Read, as the former calls Character'Read in a loop, checking for EOF as it goes. The fastest approach seems to be to read the stream elements directly, as in Stream_All2. John ---------------------------------------------------------------- John B. Matthews, M.D. jmatthews@nova.wright.edu; john_matthews@ccmail.dayton.saic.com "Whom the gods would destroy, they first invite to program in C" ------------------------------------------------------------------ --| --| iotest: time IO --| --| Author: John B. Matthews, Wright State University --| Last Modified: March 8, 1997 --| ------------------------------------------------------------------ -- results of 6 runs on a 451239 byte file: -- ave. std.dev. -- 1.00278 0.03391 sequential, one character at a time. -- 0.72499 0.02679 sequential, entire file. -- 1.26389 0.01146 stream, one character at a time. -- 1.41389 0.09738 stream, entire file 1. -- 0.65113 0.08572 stream, entire file 2. ------------------------------------------------------------------ -- build: gnatmake iotest -largs -Xlstack=500000 (or so) with Ada.Command_Line; with Ada.Sequential_IO; with Ada.Streams.Stream_IO; with Ada.Text_IO; with Calendar; use type Calendar.Time; procedure IOTest is package CLI renames Ada.Command_Line; package Text_IO renames Ada.Text_IO; package Fixed_IO is new Ada.Text_IO.Fixed_IO (Duration); Length : Natural; Start, Stop : Calendar.Time; -- Determine the size (in bytes) of the file, Name. function File_Size (Name : in String) return Natural is package SIO renames Ada.Streams.Stream_IO; F : SIO.File_Type; Size : Natural; begin SIO.Open (F, SIO.In_File, Name); Size := Integer (SIO.Size(F)); SIO.Close (F); return Size; end File_Size; procedure Sequential_One (Name : String; Length : Natural) is package SIO is new Ada.Sequential_IO (Character); F : SIO.File_Type; C : Character; begin SIO.Open (F, SIO.In_File, Name); for i in 1 .. Length loop SIO.Read (F, C); end loop; SIO.Close (F); end Sequential_One; procedure Sequential_All (Name : String; Length : Natural) is subtype Data is String (1 .. Length); package SIO is new Ada.Sequential_IO (Data); F : SIO.File_Type; S : Data; C : Character; begin SIO.Open (F, SIO.In_File, Name); SIO.Read (F, S); for i in 1 .. Length loop C := S (i); end loop; SIO.Close (F); end Sequential_All; procedure Stream_One (Name : String; Length : Natural) is package SIO renames Ada.Streams.Stream_IO; F : SIO.File_Type; S : SIO.Stream_Access; C : Character; begin SIO.Open (F, SIO.In_File, Name); S := SIO.Stream (F); for i in 1 .. Length loop Character'Read (S, C); end loop; SIO.Close (F); end Stream_One; procedure Stream_All1 (Name : String; Length : Natural) is subtype Data is String (1 .. Length); package SIO renames Ada.Streams.Stream_IO; F : SIO.File_Type; S : Data; C : Character; begin SIO.Open (F, SIO.In_File, Name); Data'Read (SIO.Stream (F), S); for i in 1 .. Length loop C := S (i); end loop; SIO.Close (F); end Stream_All1; procedure Stream_All2 (Name : String; Length : Natural) is subtype Data is String (1 .. Length); package SIO renames Ada.Streams.Stream_IO; F : SIO.File_Type; S : Ada.Streams.Stream_Element_Array (1 .. Ada.Streams.Stream_Element_Offset(Length)); L : Ada.Streams.Stream_Element_Offset; C : Ada.Streams.Stream_Element; begin SIO.Open (F, SIO.In_File, Name); SIO.Read (F, S, L); for i in 1 .. L loop C := S (i); end loop; SIO.Close (F); end Stream_All2; begin if CLI.Argument_Count = 1 then Length := File_Size (CLI.Argument (1)); Start := Calendar.Clock; Sequential_One (CLI.Argument (1), Length); Stop := Calendar.Clock; Fixed_IO.Put (Stop - Start, 0, 5); Text_IO.Put_Line (" sequential, one character at a time."); Start := Calendar.Clock; Sequential_All (CLI.Argument (1), Length); Stop := Calendar.Clock; Fixed_IO.Put (Stop - Start, 0, 5); Text_IO.Put_Line (" sequential, entire file." ); Start := Calendar.Clock; Stream_One (CLI.Argument (1), Length); Stop := Calendar.Clock; Fixed_IO.Put (Stop - Start, 0, 5); Text_IO.Put_Line (" stream, one character at a time."); Start := Calendar.Clock; Stream_All1 (CLI.Argument (1), Length); Stop := Calendar.Clock; Fixed_IO.Put (Stop - Start, 0, 5); Text_IO.Put_Line (" stream, entire file 1."); Start := Calendar.Clock; Stream_All2 (CLI.Argument (1), Length); Stop := Calendar.Clock; Fixed_IO.Put (Stop - Start, 0, 5); Text_IO.Put_Line (" stream, entire file 2."); else Text_IO.Put_Line ("Usage: iotest "); end if; end IOTest;