В данном случае, интерес представляет связка, приведенная Анонимом (reserve+copy). Вот она должна отработать поэффективней, чем вариант с интервальным конструктором, поскольку не происходит лишних телодвижений в отношении расчета дистанции:
Здравствуйте, MaximE, Вы писали:
ME>Здравствуйте, Анатолий Широков, Вы писали:
АШ>>Мне кажется странным выделять память с запасом при вполне "известном" размере файла. Во всяком случае, есть все средства для его вычисления.
ME>Конкретно у fstream — да.
ME>Случается, что istream используется как интерфейс к custom streambuf'у и получит размер нет возможности...
OE>результаты совершенно одинаковые с интервальным конструктором.
Решающую роль в производительности интервального конструктора вектора играет тип итератора. В данном случае итератор не является итератором произвольного доступа. Отсюда и провал в производительности, а именно: при вычислении дистанции и переносе памяти.
А>не может же std::istreambuf_iterator<char>() указывать на конец файла.
Нет, он не указывает на конец файла. Он есть такое значение итереатора, которое ознаечает конец файла. Начальный итератор инкрементируется до тех пор, когда не доходит до конца файла, и в этот момент его значение становится равным ограничивающему.
Да здравствует мыло душистое и веревка пушистая.
STL: банальный вопрос
От:
Аноним
Дата:
22.08.03 10:24
Оценка:
Как наилучшим образом считать файл (ifsream ) в буффер ( vector<char>)?
хоть я и использую это код, но не понимаю, как он работает.
не может же std::istreambuf_iterator<char>() указывать на конец файла.
может кто обьяснит.
спасибо
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Аноним, Вы писали:
А>>Как наилучшим образом считать файл (ifsream ) в буффер ( vector<char>)?
OE>может так?
OE>
example.cpp
D:\WORK\test2\example.cpp(846) : error C2664: '__thiscall std::vector<char,class std::allocator<char> >::std::vector<char,class std::allocator<char> >(unsigned int,const char &,const class std::allocator<char> &)' : cannot convert parameter 1 from '
class std::istreambuf_iterator<char,struct std::char_traits<char> >' to 'unsigned int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Хочу сравнить эффективность своего варианта с предложенным. Не сочтите за труд. Пусть входной файл будет в 1Mb.
А>не может же std::istreambuf_iterator<char>() указывать на конец файла.
Ээээ, в реализации, которую я смотрел, там есть указатель. Когда ты говоришь — std::istream_iterator<char>eos_it; то этот указатель инициализируется нулем. Есть еще, допустим, std::istream_iterator<char>start_it(stream_name); тут указатель инициализирован как надо. Так вот, при разыменовании итератора *start_it (поправят, если не так) проверяется, конец это файла или нет и если да, то указатель устанавливается в 0 (такая же проверка осущ. и при инициализации итератора), а потом итераторы сравниваются и цикл завершается.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Анатолий Широков, Вы писали:
АШ>>Хочу сравнить эффективность своего варианта с предложенным. Не сочтите за труд. Пусть входной файл будет в 1Mb.
OE>vc71, release, оптимизация по скорости.
OE>
OE>// file2vect.cpp : Defines the entry point for the console application.
[]
OE> vector<char> filedata( ( istreambuf_iterator<char>( inputFile ) ), istreambuf_iterator<char>() );
[]
OE>
На мой взгляд, пример этот слишком экстремален. Редко встречается, когда в пустой вектор с capacity() == 0 читают файл неизвестного размера.
Лично я, когда читаю небольшой файл, то делаю reserve() с запасом. А большие файлы, когда важна производительность, лучше отображать.
ME>На мой взгляд, пример этот слишком экстремален. Редко встречается, когда в пустой вектор с capacity() == 0 читают файл неизвестного размера.
ME>Лично я, когда читаю небольшой файл, то делаю reserve() с запасом.
Мне кажется странным выделять память с запасом при вполне "известном" размере файла. Во всяком случае, есть все средства для его вычисления.
Здравствуйте, Анатолий Широков, Вы писали:
АШ>Мне кажется странным выделять память с запасом при вполне "известном" размере файла. Во всяком случае, есть все средства для его вычисления.
Конкретно у fstream — да.
Случается, что istream используется как интерфейс к custom streambuf'у и получит размер нет возможности...
ME>На мой взгляд, пример этот слишком экстремален. Редко встречается, когда в пустой вектор с capacity() == 0 читают файл неизвестного размера.
ME>Лично я, когда читаю небольшой файл, то делаю reserve() с запасом. А большие файлы, когда важна производительность, лучше отображать.
я пробовал в этом примерчике делать сначала reserve() под размер файла, а потом
Здравствуйте, Анатолий Широков, Вы писали:
ME>>Случается, что istream используется как интерфейс к custom streambuf'у и получит размер нет возможности...
АШ>Но, попыться-то можно. См 27.6.1.3 п.
АШ>
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Анатолий Широков, Вы писали:
АШ>>Хочу сравнить эффективность своего варианта с предложенным. Не сочтите за труд. Пусть входной файл будет в 1Mb.
OE>vc71, release, оптимизация по скорости.
OE>
Здравствуйте, MaximE, Вы писали:
ME>Здравствуйте, Анатолий Широков, Вы писали:
АШ>>Мне кажется странным выделять память с запасом при вполне "известном" размере файла. Во всяком случае, есть все средства для его вычисления.
ME>Конкретно у fstream — да.
ME>Случается, что istream используется как интерфейс к custom streambuf'у и получит размер нет возможности...
Здравствуйте, <Аноним>, Вы писали:
А>не может же std::istreambuf_iterator<char>() указывать на конец файла.
24.5.1/1 istream_iterator reads (using operator>>) successive elements from the input stream for which
it was constructed. After it is constructed, and every time ++ is used, the iterator reads and stores a value of
T. If the end of stream is reached ( operator void*() on the stream returns false), the iterator
becomes equal to the end-of-stream iterator value. The constructor with no arguments
istream_iterator() always constructs an end of stream input iterator object, which is the only legitimate
iterator to be used for the end condition. The result of operator* on an end of stream is not
defined. For any other iterator value a const T& is returned. The result of operator-> on an end of
stream is not defined. For any other iterator value a const T* is returned. It is impossible to store things
into istream iterators. The main peculiarity of the istream iterators is the fact that ++ operators are not
equality preserving, that is, i == j does not guarantee at all that ++i == ++j. Every time ++ is used a
new value is read.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth