Сравнил скорость всех предложенных методов, в конце постинга сабж.
Сразу оговорюсь, что на корректность теста я не претендую, просто было интерестно померять время в конкретном случае, а именно взял текстовый файл на 6,5 метров. MSVC 7.1 /O2
Вот тестец(оставил все, как было в оригинальных постах):
выводы делать не возьмусь, замечу только, что бустовская попытка оптимизации окончилась фиаско
для меня фаворит readFile7, хотя конечно readFile3 делает всех, но ИМХО на больших размерах файлов может быть эффективней читать порциями, а не все одной сарделькой.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, eao197, Вы писали:
E>>Тоже решил пойти по следам ssm. А>... E>>Еще под Linux-ом осталось подсчитать.
А>Программа для тестирования ваша, добавил ёщё 2 варианта А>
А>void readFile8(const char *fileName)
А>{
...
А>}
A>
Это почти readFile7, насколько я смог заметить, разве что swap не используется.
A>
А вот так нельзя -- auto_ptr вызывает delete, а не delete[].
К тому же здесь памяти требуется в два раза больше.
А>readFile1 27530287 14867092 duration: 5.728 А>readFile2 27017912 14513851 duration: 9.754 А>readFile4 8349 1269 duration: 0 А>readFile5 27530287 14867092 duration: 5.728 А>readFile6 27530287 14867092 duration: 4.847 А>readFile7 27530287 14867092 duration: 2.884 А>readFile8 27530287 14867092 duration: 2.303 А>readFile9 27530287 14867092 duration: 0.521
А>Так вот...
Посмотри здесь: Re[3]: еще один отчет (Linux + простое чтение)
Здравствуйте, Ignoramus, Вы писали:
I>Вопрос вроде простой, но туплю
I>Как прочитать весь файл из ifstream в один большой string?
I>Самый простой стандартный способ?
I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)
I>Заранее спасибо.
по тестам производительности оказалось, что не все из предложенных решений (закодированных ssm) выдают одинаковые размеры результирующих строк.
E>Кто-нибудь знает, почему это происходит?
Элементарно, Ватсон!
В тех версиях, в которых размеры неправильны используется istream_iterator, все дело в его операторе++
_Myt& operator++()
{ // preincrement
_Getval();
return (*this);
}
void _Getval()
{ // get a _Ty value if possibleif (_Myistr != 0 && !(*_Myistr >> _Myval))
_Myistr = 0;
}
как видим используется оператор >> для потока, что надо сделать, что бы все заработало? Правильно!
Здравствуйте, Ignoramus, Вы писали:
I>Вопрос вроде простой, но туплю
I>Как прочитать весь файл из ifstream в один большой string?
I>Самый простой стандартный способ?
I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)
I>Заранее спасибо.
string s;
copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));
"Ignoramus" <18039@users.rsdn.ru> wrote in message news:1186457@news.rsdn.ru > Вопрос вроде простой, но туплю > > Как прочитать весь файл из ifstream в один большой string? > > Самый простой стандартный способ?
Например, такой (очень простой, не правда ли?):
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc, char * argv[])
{
ifstream in(argv[1]);
ostringstream out;
out << in.rdbuf(); // <---------
cout << out.str();
}
Здравствуйте, eao197, Вы писали:
E>А если бы завалилось все?
но мы ведь не из робкого десятка
E>Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?
А что случится, если в файле встретится байт '\0'?
Я так понимаю, что такой байт в строчку добавлять нельзя?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Кстати, в самом начале надо просто так файл считать, без теста скорости — диск, да и сама Винда его может кэшировать.
И надо б взять выборку из нескольких файлов + проводить подряд несколько тестов, меняя очередность выполнения функций,
потом посчитать среднее, стандартные отклонения, построить график и... извините, загнался .
Но нужно хотя бы просто считать файл без тестирования перед провед проведением всех тестов.
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, eao197, Вы писали:
ssm>[ccode]
E>> for( int i = 1; i < m_argc; ++i ) E>> (*a.second)( m_argv[ i ] );
ssm>[/code]
ssm>ИМХО при таком замере cash DOS может наложить более четко свой отпечаток
Думаю, что врядли. Т.к. размеры файлов очень большие и пока читается следующий большой файл, предыдущий большой файл из кэша выталкивается. Поэтому при переходе к следующему тесту все чтение начинается с чистого листа.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, zelyony, Вы писали:
Z>я видел нехорошо только в этой строке Z>а что некорректно?
Насколько я понимаю, стандарт не гарантирует, что данные в basic_string расположены последовательно (на эту тему здесь было много топиков). Поэтому, если какая-то реализация basic_string хранит строку, разбитую на несколько сегментов, то расчитывать, что ((&s[i])+1) == &s[i+1] нельзя. В твоем же примере расчет идет именно на это.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: идеём дальше
От:
Аноним
Дата:
24.05.05 12:37
Оценка:
Здравствуйте, eao197, Вы писали:
E>Тоже решил пойти по следам ssm.
... E>Еще под Linux-ом осталось подсчитать.
Программа для тестирования ваша, добавил ёщё 2 варианта
по тестам производительности оказалось, что не все из предложенных решений (закодированных ssm) выдают одинаковые размеры результирующих строк.
E>>Кто-нибудь знает, почему это происходит?
ssm>Элементарно, Ватсон! ssm>В тех версиях, в которых размеры неправильны используется istream_iterator, все дело в его операторе++
ssm>
ssm>_Myt& operator++()
ssm>{ // preincrement
ssm> _Getval();
ssm> return (*this);
ssm>}
ssm>void _Getval()
ssm>{ // get a _Ty value if possible
ssm> if (_Myistr != 0 && !(*_Myistr >> _Myval))
ssm> _Myistr = 0;
ssm>}
ssm>
ssm>как видим используется оператор >> для потока, что надо сделать, что бы все заработало? Правильно!
ssm>
ssm>std::noskipws(file);
ssm>
Да, действительно, размеры совпадают. Только не понятно, почему раньше readFile1 давала правильный результат, а readFile2 -- нет.
А readFile4 не работает на двоичных файлах, где '\0' может быть в самом файле.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
E> Только не понятно, почему раньше readFile1 давала правильный результат, а readFile2 -- нет.
потому как там используется istreambuf_iterator, который просто выгребает следующий байт, скорее всего используя get
E>А readFile4 не работает на двоичных файлах, где '\0' может быть в самом файле.
ну там ведь и указано читать строку до символа '\0'
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, eao197, Вы писали:
E>> Только не понятно, почему раньше readFile1 давала правильный результат, а readFile2 -- нет.
ssm>потому как там используется istreambuf_iterator, который просто выгребает следующий байт, скорее всего используя get
Да, это я просто к вечеру уже перестал различать istream_iterator и istreambuf_iterator
E>>А readFile4 не работает на двоичных файлах, где '\0' может быть в самом файле.
ssm> ну там ведь и указано читать строку до символа '\0'
ssm>
ssm> getline(inp, s, '\0');
ssm>
Ну да, это-то я увидел. Я просто подчеркнул, что применять readFile4 можно только на текстовых файлах. Т.е. лучше ее не применять
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: идеём дальше
От:
Аноним
Дата:
25.05.05 11:40
Оценка:
Здравствуйте, eao197, Вы писали:
E>А вот так нельзя -- auto_ptr вызывает delete, а не delete[]. E>К тому же здесь памяти требуется в два раза больше.
Про delete спасибо, не знал.
А нащёт памяти я не понял. Зачем в 2 раза больше?
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, eao197, Вы писали:
E>>А вот так нельзя -- auto_ptr вызывает delete, а не delete[]. E>>К тому же здесь памяти требуется в два раза больше.
А>Про delete спасибо, не знал. А>А нащёт памяти я не понял. Зачем в 2 раза больше?
Ну вот смотри, пусть наш файл имеет размер 50Mb:
// Вот первые 50Mb.
std::auto_ptr<char> buf(new char[size]);
in.read(buf.get(), size);
// А вот и вторые 50.
std::string s(buf.get(), in.gcount());
// Вот на этой точке у нас занято 100Mb памяти, причем это две одинаковых копии.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Тоже решил пойти по следам ssm.
E>Собрал вот такую программку:
//skipped
E>Тестировал на файлах от ~35Mb до ~50Mb. Забавно, что readFile2, readFile4, readFile6 выдают в результате неправильные размеры
E>На Visual С++ 7.1 получил: E>
Прошу прощения что может быть не совсем по теме спрашиваю.
Мне надо прочитать файл 10Мб. И надо вывести результаты в браузере IE7, то есть запустить программу как cgi скрипт.
Попробовал вариант :
s.erase();
if(in.bad()) return "";
//
// attempt to grow string buffer to match file size,
// this doesn't always work...
s.reserve(in.rdbuf()->in_avail());
char c;
while(in.get(c))
{
// use logarithmic growth stategy, in case
// in_avail (above) returned zero:
if(s.capacity() == s.size())
s.reserve(s.capacity() * 3);
s.append(1, c);
}
в Opera отрабатывает нормально, а в IE7 начальный текст выкидывается а потом IE7 уходит в себя и не возвращается.
Подскажите пожалуйста, как можно исправить ситуацию?
Может быть периодически опустошать буфер или читать другим способом?
Заранее спасибо!