Читаем из stdin построково:
======== Ada =========
with Ada.Text_IO; use Ada.Text_IO;
procedure StdIn_Reader is
Seq : String(1 .. 60);
J : Natural;
begin
while not End_Of_File loop
Get_Line (Seq, J);
end loop;
end StdIn_Reader;
=====================
======== C++ =========
#include <iostream>
using namespace std;
int main()
{
cin.sync_with_stdio(false);
char line[61];
while (!cin.eof())
{
cin.getline(line,61);
}
return 0;
}
====================
На stdin подаем через перенаправление ввода (т.е. из файла,
называющимся в данном конкретном случае, stdin (я его так обозвал)). В файл размером примерно 250 Мб, длина каждой строки примерно 60
символов:
$ time ./ada < stdin
real 0m31.856s
user 0m10.457s
sys 0m0.684s
$ time ./cpp < stdin
real 0m5.911s
user 0m1.308s
sys 0m0.568s
Грубо говоря, получаем что ада читает этот файл за 10 секунд, а С++ за 1,5 секунды. Разница примерно в 7 раз. Почему? Как исправить?
PS. компиляция производилась с опциями по умолчанию. Т.е.:
gnat make StdIn_Reader.adb
и
g++ stdin_reader.cpp
On Mon, 19 May 2008 04:00:18 +0400, you wrote:
Грубо говоря, получаем что ада читает этот файл за 10 секунд, а С++ за 1,5 секунды. Разница примерно в 7 раз. Почему? Как исправить?
1. Text_IO предназначен для форматного ввода-вывода и имеет богатые, но увы, мало кому нужные возможности, которые, однако не допускают эффективной реализации. Для чтения потоков используйте Ada.Streams.
(Кстати, и конец строки, Text_IO во многих случаях может определять не так, как Вам было бы нужно.)
2. Если уж Text_IO, то не надо использовать End_OF_File, он работает (в ОС типа Windows и Unix, не имеющих файлов записей) через просмотр вперед, и практически в любой ситуации вреден. Конец файла должен ловится по исключению End_Error. Это и программно чище, и быстрее.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
1. Text_IO предназначен для форматного ввода-вывода и имеет богатые, но увы, мало кому нужные возможности, которые, однако не допускают эффективной реализации. Для чтения потоков используйте Ada.Streams.
(Кстати, и конец строки, Text_IO во многих случаях может определять не так, как Вам было бы нужно.)
2. Если уж Text_IO, то не надо использовать End_OF_File, он работает (в ОС типа Windows и Unix, не имеющих файлов записей) через просмотр вперед, и практически в любой ситуации вреден. Конец файла должен ловится по исключению End_Error. Это и программно чище, и быстрее.
Переписал:
==========================
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams;
procedure StdIn_Reader is
subtype MyStr is String(1 .. 60);
Seq : MyStr;
S : access Root_Stream_Type;
begin
S := Stream(Standard_Input);
loop
MyStr'Read(S,Seq);
end loop;
end StdIn_Reader;
==========================
Запустил:
$ time ./ada < stdin
raised ADA.IO_EXCEPTIONS.END_ERROR : s-stratt.adb:184
real 1m53.850s
user 0m58.176s
sys 0m1.104s
По моему, быстрее не стало ;-)
On Mon, 19 May 2008 22:52:54 +0400, you wrote:
Переписал:
==========================
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Streams; use Ada.Streams;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams;
procedure StdIn_Reader is
subtype MyStr is String(1 .. 60);
Seq : MyStr;
S : access Root_Stream_Type;
begin
S := Stream(Standard_Input);
loop
MyStr'Read(S,Seq);
Это уже новая тема. Как помнится, в GNAT S'Read для String (и массивов вообще) не оптимизирован, он вызывает Read на каждый отдельный Character. Попробуйте читать Stream_Element_Array непосредственно из потока. Или переопределите MyStr'Read, чтобы он читал весь блок за один раз.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Это уже новая тема. Как помнится, в GNAT S'Read для String (и массивов вообще) не оптимизирован, он вызывает Read на каждый отдельный Character.
Вы абсолютно правы. Если мне не изменяет память, мы это починили пару месяцев назад, так что надеюсь GPL 2008 будет пошустрее на этом
примере.
ВФ
Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти