Навеяло одной из предыдущих веток. Действительно ли есть существенные различия в производительности stdio и iostream?? Это общепризнанно или как? Для меня рушится целый мир.
> Навеяло одной из предыдущих веток. Действительно ли есть существенные различия в производительности stdio и iostream?? Это общепризнанно или как? Для меня рушится целый мир.
Да, есть. iostream "искаропки" помедленнее.
Хотя там вроде можно буфер побольше установить... Или я неправ?
> блин ну напишите тест на сто строк да измерьте
$ cat test_io.c
#include <stdio.h>
int main()
{
int i;
for (i=100000000; i--; )
{
printf("%s", "some not very long line\n");
}
return 0;
}
$ gcc -O3 test_io.c
$ time ./a.out > /dev/null
real 0m5.294s
user 0m5.244s
sys 0m0.052s
$ ls -s a.out
8 a.out
$ cat test_io.cpp
#include <iostream>
int main()
{
int i;
for (i=100000000; i--; )
{
std::cout << "some not very long line\n";
}
return 0;
}
$ g++ -O3 test_io.cpp
$ time ./a.out > /dev/null
real 0m7.101s
user 0m7.052s
sys 0m0.048s
$ ls -s a.out
8 a.out
Скажи еще что тебе нравится архитектура <iostream> и ты в ней полноситью разобрался. В Жабе например InputStream - это простой как пробка абстрактный класс с дюжиной виртуальных методов. Можно in-place завраппить в InputStream любой массив или сокет и передать куда угодно. И будет работать как часы. Для сравнения можно попытаться завраппить TCP сокет в std::istream.
Если сделать навороченную форматную линию, то printf сильно сольет форматированию потоковыми манипуляторами. По крайней мере, лет 5 назад на ГЦЦ было так. Там все форматирование на парзингом форматной строки делалось, а в компайлтайм инлайнилось.
> Если сделать навороченную форматную линию, то printf сильно сольет форматированию потоковыми манипуляторами.
Надо же, наоборот!
В 2001 году спорили тут, что быстрее -- потоки с манипуляторами тогда выиграли. Сейчас простой тест прогнал:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int i;
for (i=10000000; i--; )
{
std::cout << fixed << setprecision(3) << 1.0 <<' '<<
setprecision(5)<< 2.0
<<' '<< setprecision(6)<<3.0<<' '
<< setprecision(7)<<4.0 << endl;
}
return 0;
}
-- сливает printf("%.3f %.5 %.6 %.7\n", 1.0,2.0,3.0,4.0);
в разы (в смысле, printf быстрее)...
вот чтение из COM порта:
char next_byte;
while(serial_port.rdbuf()->in_avail() > 0)
{
serial_port.get(next_byte);
// save next_byte somewhere...
}
Всё стандартное. Сам SerialStream унаследован от std::iostream.
>Дядь, ты с кем сейчас разговаривал? Растолкуй для тупых математиков.
class BufferedInputStream : public BasicInputStream {
std::auto_ptr<BasicInputStream> _stream;
unsigned char* _buffer;
public:
BufferedInputStream(std::auto_ptr<BasicInputStream> stream, std::size_t bufferSize);
/// Implemented virtual methods
};
BufferedInputStream::BufferedInputStream(std::auto_ptr<BasicInputStream> stream, std::size_t bufferSize)
:_stream(stream), _buffer(::operator new[](bufferSize))
{}
/// Buffering logic
Надеюсь более - менее понятен принцип по которому один такой стрим аггрегируется в другой. И ясен принцип по которому один стрим владеет другим.
>Всё стандартное. Сам SerialStream унаследован от std::iostream.
Мой интерфейс занимает ~200 байт. <iostream> суммарно со всеми вложенностями занимает 400 кб.
И при этом функционал в общем такой же - ведь единственный вменяемый способ чего-то прочитать из std::istream это сделать
std::string userInput;
std::getline(userInput, std::cin);
// parse userInput using regexps or someting like lex/yacc....
Следовательно 400 Кб всех эти бесконечных специализаций оператора >> бесполезны и нахрен не нужны.
Кстати, я недавно с товарищем спорил на эту же тему. Он большой любитель istream. Доводы приводил такие же как и ты - не помогло. Думаю и тут не поможет. Просто забей. У людей стереотипы java-плохо.
> И при этом функционал в общем такой же - ведь единственный вменяемый способ чего-то прочитать из std::istream это сделать std::getline(userInput, std::cin);
Tensor<2,3,double> t;
cin >> t;
Перепиши это "вменяемым" способом а потом задумайся, насколько получилось вменяемо и читабельно :)
> Следовательно 400 Кб всех эти бесконечных специализаций оператора >> бесполезны и нахрен не нужны.
Не умеешь пользоваться -- не говори, что они не нужны.
>Я бы назвал такое половым извращением. Уже за auto_ptr.
auto_ptr - часть C++ std lib. Или в какой-то новой книжке по С++ его объявили "злом"?.
>Не увидел проблемы. Да, за временем жизни переменной надо следить, но это надо делать везде, а не только в iostream.
Проблема в том что весь <iostream> - это индусокод. Интерфейс должен быть необходимым и достаточным. Стрим в частности должен читать чанки байт и ничего более. Интерпретировать информацию должны парсеры навешивающиеся сверху на стрим.
А хуле толку от этих 200 байт, когда любой класс, реализующий этот интерфейс, превратится в конце концов в копию iostream'a ? Подсчёт количества переданных байт, флаги ошибок, расположения указателя внутри потока, и прочее прочее прочее... Всё это будешь навешивать на каждую конкретную реализацию? (Только не говори что это не нужно)
>Tensor<2,3,double> t; >cin >> t; >Перепиши это "вменяемым" способом а потом задумайся, насколько получилось вменяемо и читабельно :)
Tensor<2,3,double> t; readTensor(t, std::cin);
>> Следовательно 400 Кб всех эти бесконечных специализаций оператора >> бесполезны и нахрен не нужны.
>Не умеешь пользоваться -- не говори, что они не нужны.
Хорошо, так: 1) Зачем они нужны когда есть регулярные выражения и yacc ? 2) Зачем мне инклюдить 400 Кб говна из <iostream>, когда мне надо просто тупо читать чанки бинарных данных с внешнего устройиства?
то что ты привёл - это примитив на уровне 1-го курса. Из разряда задач по "базам данных" в текстовых файлах. Если тебе нужна такая примитивщина, никто не запрещает сделать свои 200-байтные интерфейсы и пользоваться. Кому нужен функционал - те пользуют что-то более вменяемое (iostream).
>то что ты привёл - это примитив на уровне 1-го курса.
Это интерфейс типа COM-овского IStream. Он удовлетворяет критериям "необходимости" и "достаточности". Кому надо парсить сложный ввод навесят сами на него нужный функционал, который вероятно идет в той же библиотеке в других заголовочных файлах.
>Кому нужен функционал - те пользуют что-то более вменяемое (iostream).
Нет, iostream невменяем. Лучше тогда уж использовать <stdio.h>.
>Теперь напиши ещё readInt, readDouble, readString и т.д. И увидишь всё те же 400 кб "говна", только в профиль :)
Во-первых функция readInt будет работать через getline + регулярное выражение, следовательно оно не будет оставлять стрим в непонятном состоянии после того как пользователь ввел "13BoZo". Во вторых, там надо будет сделать диагностику парсинга чтобы выдать вменяемое сообщение об ошибке. В третьих, если ввод осуществляется с tty неплохо бы дать возможность попробовать еще раз. Ну и в четвертых 400 Кб там не будет, поскольку парсинг текстовых данных никакого отношения к стримам не имеет, следовательно он будет помещен в отдельный модуль.
>> Хорошо, так: 1) Зачем они нужны когда есть регулярные выражения и yacc?
>Зачем нужна вилка, когда есть ложка?
Размером pcre AFAIK намного меньше половины мегабайта (размер iostream), и работает в разы надежней. И в разы гибче.
>> 2) Зачем мне инклюдить 400 Кб говна из <iostream>, когда мне надо просто тупо читать чанки бинарных данных с внешнего устройиства?
>Тебя под страхом смерти заставляют использовать iostream для этой задачи?
Типичное сиплюсплюсное виляние. Например в твоей любимой Java есть пакет java.nio для асинхронного блочного ввода-вывода c использованием буферов фиксированного размера. На Линуксе оно реализовано через epoll(). Есть выбор какой-то блин.
Предлагаю ещё пофантазировать на тему: распарсить одним разом матрицу в формате "высота ширина\nстрока 1\nстрока 2\n...строка n". Одной функцией. Сколько там данных потребуется прочитать?
> Размером pcre AFAIK намного меньше половины мегабайта (размер iostream), и работает в разы надежней. И в разы гибче.
Угу, значит уже часть stl работает ненадёжно... Кстати, pcre -- не часть плюсового стандарта, а только часть posix-а. Но явисты, конечно, знают, что должно быть в стандарте цпп :)
>Кстати, pcre -- не часть плюсового стандарта, а только часть posix-а
Т.н. плюсовый стандарт - интересная вещь. Он неявно подразумевает что на машине есть 32-битовая виртуальная память, но при этом считает что на машине нету curses/ncurses.
>Но явисты, конечно, знают, что должно быть в стандарте цпп :)