C++ 3d.Комментарии



Ввод символов - часть 2


int Ok() { return fd!=-1; }

int gchar() { return (gptr<bend) ? *gptr++ : uflow(); } };

int File::uflow() { if (!Ok()) return EOF;

int rd=read(fd, buf, BUFSIZ); if (rd<=0) { // ошибка или EOF close(fd); fd=-1;

return EOF; }

gptr=buf; bend=buf+rd;

return *gptr++; }

void work3(char* fn) { File fil(fn);

if (!fil.Ok()) return;

time_t t1; time(&t1);

long count=0; while (fil.gchar()!=EOF) count++;

time_t t2; time(&t2);

cout<<count<<" bytes per "<<t2-t1<<" sec.\n" ; }

Ее нужно запускать с двумя параметрами. Первый параметр -- это имя (большого) файла для чтения, а второй -- цифра 1, 2 или 3, выбирающая функцию workc(), workcpp() или work3() соответственно. Только не забудьте про дисковый кэш, т.е. для получения объективных результатов программу нужно запустить несколько раз для каждого из вариантов.

Необычным местом здесь является функция work3() и соответствующий ей класс File. Они написаны специально для проверки "честности" реализации стандартных средств ввода-вывода C -- FILE*. Если вдруг окажется, что workc() работает существенно медленнее work3(), то вы имеете полное право назвать создателей такой библиотеки, как минимум, полными неучами.

А сейчас попробуем получить информацию к размышлению: проведем серию контрольных запусков и посмотрим на результат.

И что же нам говорят безжалостные цифры? Разница в разы! А для одного широко распространенного коммерческого пакета (не будем показывать пальцем) она порой достигала 11 раз!!!

Стоит только взглянуть на определения вызываемых функций, как ответ сразу станет очевидным.

Для C с его getc() в типичной реализации мы имеем: #define getc(f) ((--((f)->level) >= 0) ? (unsigned char)(*(f)->curp++) : _fgetc (f))

Т.е. коротенький макрос вместо функции. Как говорится -- всего-ничего. А вот для C++ стандарт требует столько, что очередной раз задаешься вопросом: думали ли господа-комитетчики о том, что горькие плоды их творчества кому-то реально придется применять?!




Содержание  Назад  Вперед