Re[4]: весь файл из ifstream >> string
От: doig-u Россия  
Дата: 24.05.05 11:03
Оценка:
Кстати, в самом начале надо просто так файл считать, без теста скорости — диск, да и сама Винда его может кэшировать.
И надо б взять выборку из нескольких файлов + проводить подряд несколько тестов, меняя очередность выполнения функций,
потом посчитать среднее, стандартные отклонения, построить график и... извините, загнался .
Но нужно хотя бы просто считать файл без тестирования перед провед проведением всех тестов.
Re[3]: еще один отчет
От: ssm Россия  
Дата: 24.05.05 11:16
Оценка:
Здравствуйте, eao197, Вы писали:


[ccode]

E> for( int i = 1; i < m_argc; ++i )

E> (*a.second)( m_argv[ i ] );

[/code]

ИМХО при таком замере cash DOS может наложить более четко свой отпечаток
Re[3]: еще один отчет (Linux + простое чтение)
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 11:16
Оценка: +1
E>На Visual С++ 7.1 получил:
E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 22.92
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 36.843
E>readFile4  6  5  3  3  5 duration: 0.047
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 25.655
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 35.42
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.984
E>


E>На Borland C++ 5.6:

E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 17.203
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 50.234
E>readFile4  6  5  3  3  5 duration: 0.016
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 34.938
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 62.593
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 23.282
E>


E>На MinGW C++ (3.2.3 20030504-1):

E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 34.9
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 62.562
E>readFile4  6  5  3  3  5 duration: 0.157
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 55.983
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 59.307
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.47
E>


E>Еще под Linux-ом осталось подсчитать.


Вот что получилось под Slackware 10.0, GNU C++ 3.3.4:
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 31.04
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 38.23
readFile4  6  5  3  3  5 duration: 0
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 38.07
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 37.2
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 2.19


После этого я добавил еще две функции:
void
readFile8( const char * file_name )
    {
        std::ifstream in( file_name, std::ios::binary );
        std::vector< char > buf( 4096 );
        std::string s;

        while( in )
            {
                in.read( &buf[ 0 ], buf.size() );
                s.append( &buf[ 0 ], in.gcount() );
            }

        std::cout << " " << s.length() << " ";
    }

void
readFile9( const char * file_name )
    {
        std::ifstream in( file_name, std::ios::binary );
        std::vector< char > buf( 4096 );
        std::string s;

        in.seekg( 0, std::ios::end );
        s.reserve( in.tellg() );
        in.seekg( 0 );

        while( in )
            {
                in.read( &buf[ 0 ], buf.size() );
                s.append( &buf[ 0 ], in.gcount() );
            }

        std::cout << " " << s.length() << " ";
    }


И вот их результаты под Linux-ом в сравнении с readFile7:
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 2.2
readFile8  50996600  46676172  40532459  40480453  36657475 duration: 1.4
readFile9  50996600  46676172  40532459  40480453  36657475 duration: 0.78




Для себя я сделал вывод -- проще нужно быть


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: еще один отчет
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 11:19
Оценка:
Здравствуйте, 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++.
Re[5]: отчет DevPartner
От: zelyony  
Дата: 24.05.05 12:05
Оценка:
я видел нехорошо только в этой строке
а что некорректно?
Posted via RSDN NNTP Server 1.9
Re[6]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 12:18
Оценка:
Здравствуйте, 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 варианта
void readFile8(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);

    in.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = in.tellg();
    in.seekg( 0);

    std::string s(size,'\0');
    ostringstream out(s); 

    out << in.rdbuf(); 

    std::cout << " " << s.length() << " ";
}

void readFile9(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);

    in.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = in.tellg();
    in.seekg( 0);

    std::auto_ptr<char> buf(new char[size]);
    in.read(buf.get(), size);
    std::string s(buf.get(), in.gcount());
    
    std::cout << " " << s.length() << " ";
}

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[4]: идеём дальше
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 12:45
Оценка: 2 (1) +1
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, eao197, Вы писали:


E>>Тоже решил пойти по следам ssm.

А>...
E>>Еще под Linux-ом осталось подсчитать.

А>Программа для тестирования ваша, добавил ёщё 2 варианта

А>
А>void readFile8(const char *fileName)
А>{
...
А>}
A>

Это почти readFile7, насколько я смог заметить, разве что swap не используется.

A>
А>void readFile9(const char *fileName)
А>{
А>    std::ifstream in(fileName, std::ios::binary);

А>    in.seekg( 0, std::ios_base::end);
А>    std::fstream::pos_type size = in.tellg();
А>    in.seekg( 0);

А>    std::auto_ptr<char> buf(new char[size]);
А>    in.read(buf.get(), size);
А>    std::string s(buf.get(), in.gcount());
    
А>    std::cout << " " << s.length() << " ";
А>}
А>


А вот так нельзя -- 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 + простое чтение)
Автор: eao197
Дата: 24.05.05
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
А все ли решения работают?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 12:50
Оценка:
Вот здесь
Автор: eao197
Дата: 24.05.05
по тестам производительности оказалось, что не все из предложенных решений (закодированных ssm) выдают одинаковые размеры результирующих строк.

Кто-нибудь знает, почему это происходит?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: А все ли решения работают?
От: ssm Россия  
Дата: 24.05.05 13:50
Оценка: 10 (1)
Здравствуйте, eao197, Вы писали:

E>Вот здесь
Автор: eao197
Дата: 24.05.05
по тестам производительности оказалось, что не все из предложенных решений (закодированных ssm) выдают одинаковые размеры результирующих строк.


E>Кто-нибудь знает, почему это происходит?


Элементарно, Ватсон!
В тех версиях, в которых размеры неправильны используется istream_iterator, все дело в его операторе++


_Myt& operator++()
{    // preincrement
  _Getval();
  return (*this);
}

void _Getval()
{    // get a _Ty value if possible
  if (_Myistr != 0 && !(*_Myistr >> _Myval))
    _Myistr = 0;
}


как видим используется оператор >> для потока, что надо сделать, что бы все заработало? Правильно!

std::noskipws(file);
Re[2]: весь файл из ifstream >> string
От: Аноним  
Дата: 24.05.05 14:10
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Например, такой (очень простой, не правда ли?):

A>
A>#include <iostream>              
A>#include <fstream>               
A>#include <sstream>               
                                 
A>using namespace std;             
                                 
A>int main(int argc, char * argv[])
A>{                                
A>    ifstream in(argv[1]);        
A>    ostringstream out;           
A>    out << in.rdbuf();  // <---------
A>    cout << out.str();           
A>}                                
A>


Пользуюсь именно таким, до сих про проблем не было. Посмотрев на код, который приводят участники задумался — м.б. это не правильно?
Re[2]: А все ли решения работают?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 14:14
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, eao197, Вы писали:


E>>Вот здесь
Автор: eao197
Дата: 24.05.05
по тестам производительности оказалось, что не все из предложенных решений (закодированных 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++.
Re[3]: А все ли решения работают?
От: ssm Россия  
Дата: 24.05.05 14:24
Оценка:
Здравствуйте, eao197, Вы писали:


E> Только не понятно, почему раньше readFile1 давала правильный результат, а readFile2 -- нет.


потому как там используется istreambuf_iterator, который просто выгребает следующий байт, скорее всего используя get

E>А readFile4 не работает на двоичных файлах, где '\0' может быть в самом файле.


ну там ведь и указано читать строку до символа '\0'

  getline(inp, s, '\0');
Re[3]: весь файл из ifstream >> string
От: ssm Россия  
Дата: 24.05.05 14:34
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Пользуюсь именно таким, до сих про проблем не было. Посмотрев на код, который приводят участники задумался — м.б. это не правильно?


правильно, я читал об этом у Страуструпа(и помоему у Маерса)
Re[4]: А все ли решения работают?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 14:37
Оценка:
Здравствуйте, 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 раза больше?
Re[6]: идеём дальше
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 25.05.05 11:56
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Здравствуйте, 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++.
Re[3]: еще один отчет
От: varnie  
Дата: 20.06.08 16:18
Оценка:
Здравствуйте, eao197, Вы писали:

E>Тоже решил пойти по следам ssm.


E>Собрал вот такую программку:

//skipped

E>Тестировал на файлах от ~35Mb до ~50Mb. Забавно, что readFile2, readFile4, readFile6 выдают в результате неправильные размеры


E>На Visual С++ 7.1 получил:

E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 22.92
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 36.843
E>readFile4  6  5  3  3  5 duration: 0.047
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 25.655
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 35.42
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.984
E>


E>На Borland C++ 5.6:

E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 17.203
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 50.234
E>readFile4  6  5  3  3  5 duration: 0.016
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 34.938
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 62.593
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 23.282
E>


E>На MinGW C++ (3.2.3 20030504-1):

E>
E>readFile1  50996600  46676172  40532459  40480453  36657475 duration: 34.9
E>readFile2  49827578  45636872  39624753  39557524  35823658 duration: 62.562
E>readFile4  6  5  3  3  5 duration: 0.157
E>readFile5  50996600  46676172  40532459  40480453  36657475 duration: 55.983
E>readFile6  49827578  45636872  39624753  39557524  35823658 duration: 59.307
E>readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.47
E>


E>Еще под Linux-ом осталось подсчитать.


под FreeBSD 7/0 Release:
на GCC 4.2.1 :
(тестил на файлах по 7-10 МB)
readFile1  9227304  10623336  10169386  9137689  18423226 duration: 7.1875
readFile2  8944789  10406076  9956451  8885937  18009017 duration: 7.02344
readFile4  5  5  5  5  5 duration: 0
readFile5  9227304  10623336  10169386  9137689  18423226 duration: 2.76562
readFile6  8944789  10406076  9956451  8885937  18009017 duration: 5.60938
readFile7  9227304  10623336  10169386  9137689  18423226 duration: 0.375
"Я женился на первой же женщине, которая обратилась ко мне по мейлу." © Л. Торвальдс
Re[4]: еще один отчет
От: andrew2008  
Дата: 15.10.08 10:09
Оценка:
Прошу прощения что может быть не совсем по теме спрашиваю.
Мне надо прочитать файл 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 уходит в себя и не возвращается.
Подскажите пожалуйста, как можно исправить ситуацию?
Может быть периодически опустошать буфер или читать другим способом?
Заранее спасибо!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.