Re: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 09:30
Оценка: 6 (3)
Здравствуйте, Ignoramus, Вы писали:

Сравнил скорость всех предложенных методов, в конце постинга сабж.
Сразу оговорюсь, что на корректность теста я не претендую, просто было интерестно померять время в конкретном случае, а именно взял текстовый файл на 6,5 метров. MSVC 7.1 /O2
Вот тестец(оставил все, как было в оригинальных постах):


#include <fstream>
#include <algorithm>
#include <string>
#include <sstream>


using namespace std;

void readFile1(const char *fileName)
{
    std::ifstream ifs(fileName, std::ios::binary);
    std::string s;
    copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));

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

void readFile2(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    std::string str;

    std::copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));

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

void readFile3(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    string str;

    file.seekg( 0, ios_base::end);
    std::ifstream::pos_type len = file.tellg();
    file.seekg( 0);
    str.resize( len);
    file.read( (char*)str.data(), len); 

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

void readFile4(const char *fileName)
{
    string s;
    ifstream inp(fileName, std::ios::binary);
    getline(inp, s, '\0');

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

void readFile5(const char *fileName)
{
    string s;
    ifstream is(fileName, std::ios::binary);

    //
    // attempt to grow string buffer to match file size,
    // this doesn't always work...
    s.reserve(is.rdbuf()->in_avail());
    char c;
    while(is.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);
    }

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

void readFile6(const char *fileName)
{
    typedef std::istream_iterator<char> IIC;

    std::ifstream file(fileName, std::ios::binary);    

    file.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = file.tellg();
    file.seekg( 0);
    
    std::string str_file;
    str_file.reserve(size);
    std::copy(IIC(file), IIC(), std::back_inserter(str_file));

    std::cout << " " << str_file.length() << " ";

}

void readFile7(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);
    ostringstream out;           
    out << in.rdbuf(); 

    string s;
    out.str().swap(s); 

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

typedef void (*PF)(const char*);

class FReadFile
{
public:
    FReadFile(const char *fileName)
        :    fileName(fileName)
    {
    }

    void operator()(PF pf) const
    {
        pf(fileName);
    }

private:
    const char *fileName;
};

int main() 
{ 
    

    const size_t readersCount = 7;
    PF readers[readersCount] = {
        readFile1, readFile2, readFile3, 
        readFile4, readFile5, readFile6, 
        readFile7
    };
    
    FReadFile func("c:\\temp\\prof\\test.txt");

    for(int i = 0; i < 10; ++i)
    {
        std::for_each(readers, readers + readersCount, func);
        std::cout << i << "\n";
    }    

}


собственно сабж.

"Method Name","% in Method","% with Children","Called","Average"
"readFile5",   "43,9",       "44,0",           "10",    "3836250,8"
"readFile2",   "17,5",       "17,6",           "10",    "1526903,1"
"readFile6",   "14,9",       "15,0",           "10",    "1304416,2"
"readFile1",   "11,6",       "11,8",           "10",    "1015325,8"
"readFile4",    "7,1",        "7,3",           "10",     "622452,2"
"readFile7",    "3,6",        "3,8",           "10",     "317294,6"
"readFile3",    "0,3",        "0,4",           "10",      "27201,5"


выводы делать не возьмусь, замечу только, что бустовская попытка оптимизации окончилась фиаско
для меня фаворит readFile7, хотя конечно readFile3 делает всех, но ИМХО на больших размерах файлов может быть эффективней читать порциями, а не все одной сарделькой.
Re: весь файл из ifstream >> string
От: Valodzka Беларусь  
Дата: 23.05.05 21:37
Оценка: 5 (1) +1
Здравствуйте, Ignoramus, Вы писали:

I>Как прочитать весь файл из ifstream в один большой string?


Обединяя всё вышенаписанное в нормальный вариант:

typedef std::istream_iterator<char> IIC;

file.seekg( 0, std::ios_base::end);
std::fstream::pos_type size = file.tellg();
file.seekg( 0);
//теперь так
std::string str_file;
str_file.reserve(size);
std::copy(IIC(file), IIC(), std::back_inserter(str_file));
Не перебивайте меня, когда я вас перебиваю
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++.
Re: весь файл из ifstream >> string
От: Аноним  
Дата: 24.05.05 07:04
Оценка: 1 (1) +1
Здравствуйте, Ignoramus, Вы писали:

I>Вопрос вроде простой, но туплю


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)


I>Заранее спасибо.


ifstream file("some.txt");
typedef istreambuf_iterator<char> iter;
string str( (iter(file)), iter() );
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: весь файл из ifstream >> string
От: avitya  
Дата: 23.05.05 11:56
Оценка: 4 (1)
Здравствуйте, Ignoramus, Вы писали:

I>Вопрос вроде простой, но туплю


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


I>(Если просто ifs >> s то читается строка до первого разделителя между словами...)


I>Заранее спасибо.

string s;
copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));
Re: весь файл из ifstream >> string
От: A. Fedotov Украина  
Дата: 23.05.05 12:01
Оценка: 4 (1)
Здравствуйте, Ignoramus, Вы писали:


    fstream file("c:\\1.txt");
    string str;

    copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));
Re: весь файл из ifstream >> string
От: alexeiz  
Дата: 24.05.05 05:47
Оценка: 3 (1)
"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();           
}
Posted via RSDN NNTP Server 1.9
Re[2]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 09:40
Оценка: +1
Здравствуйте, ssm, Вы писали:

Так ведь:

ssm>
ssm>void readFile3(const char *fileName)
ssm>{
ssm>    std::ifstream file(fileName, std::ios::binary);
ssm>    string str;

ssm>    file.seekg( 0, ios_base::end);
ssm>    std::ifstream::pos_type len = file.tellg();
ssm>    file.seekg( 0);
ssm>    str.resize( len);
ssm>    file.read( (char*)str.data(), len); 

ssm>    std::cout << " " << str.length() << " ";
ssm>}
ssm>


некорректен.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 10:15
Оценка: :)
Здравствуйте, eao197, Вы писали:

E>А если бы завалилось все?


но мы ведь не из робкого десятка

E>Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?


никак размер файла все-таки 6,5 метров
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++.
весь файл из ifstream >> string
От: Ignoramus  
Дата: 23.05.05 11:49
Оценка:
Вопрос вроде простой, но туплю

Как прочитать весь файл из ifstream в один большой string?

Самый простой стандартный способ?

(Если просто ifs >> s то читается строка до первого разделителя между словами...)

Заранее спасибо.
Re: весь файл из ifstream >> string
От: zelyony  
Дата: 23.05.05 12:02
Оценка:
file.seekg( 0, ios_base::end);
pos_type len = file.tellg();
file.seekg( 0);
str.resize( len);
file.read( (char*)str.data(), len); // нехорошо
Posted via RSDN NNTP Server 1.9
Re: весь файл из ifstream >> string
От: Chorkov Россия  
Дата: 23.05.05 12:09
Оценка:
Здравствуйте, Ignoramus, Вы писали:

    string s;
    ifstream inp("test.txt");
    getline(inp, s, '\0');
Re: весь файл из ifstream >> string
От: ssm Россия  
Дата: 23.05.05 12:18
Оценка:
Здравствуйте, Ignoramus, Вы писали:


I>Как прочитать весь файл из ifstream в один большой string?


I>Самый простой стандартный способ?


так делают парни из boost:

void load_file(std::string& s, std::istream& is)
{
   s.erase();
   if(is.bad()) return;
   //
   // attempt to grow string buffer to match file size,
   // this doesn't always work...
   s.reserve(is.rdbuf()->in_avail());
   char c;
   while(is.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);
   }
}
Re[2]: весь файл из ifstream >> string
От: Erop Россия  
Дата: 24.05.05 04:39
Оценка:
Здравствуйте, Valodzka, Вы писали:

V>
V>typedef std::istream_iterator<char> IIC;

V>file.seekg( 0, std::ios_base::end);
V>std::fstream::pos_type size = file.tellg();
V>file.seekg( 0);
V>//теперь так
V>std::string str_file;
V>str_file.reserve(size);
V>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>


А что случится, если в файле встретится байт '\0'?
Я так понимаю, что такой байт в строчку добавлять нельзя?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: весь файл из ifstream >> string
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 07:35
Оценка:
Здравствуйте, Erop, Вы писали:

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


V>>
V>>typedef std::istream_iterator<char> IIC;

V>>file.seekg( 0, std::ios_base::end);
V>>std::fstream::pos_type size = file.tellg();
V>>file.seekg( 0);
V>>//теперь так
V>>std::string str_file;
V>>str_file.reserve(size);
V>>std::copy(IIC(file), IIC(), std::back_inserter(str_file));
V>>


E>А что случится, если в файле встретится байт '\0'?

E>Я так понимаю, что такой байт в строчку добавлять нельзя?

А почему в std::string нельзя '\0' добавить? В чем проблема-то?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: отчет DevPartner
От: ssm Россия  
Дата: 24.05.05 09:49
Оценка:
Здравствуйте, eao197, Вы писали:

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


E>Так ведь:


ssm>>
ssm>>void readFile3(const char *fileName)
ssm>>


E>некорректен.



"оставил все, как было в оригинальных постах"

Re[4]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 09:53
Оценка:
Здравствуйте, ssm, Вы писали:

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


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


E>>Так ведь:


ssm>>>
ssm>>>void readFile3(const char *fileName)
ssm>>>


E>>некорректен.



ssm>

ssm>"оставил все, как было в оригинальных постах"


А если бы завалилось все?

Кстати, а как поменяются результаты измерений, если из каждой функции убрать финальную std::cout << " " << s.length()... ?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: отчет DevPartner
От: zelyony  
Дата: 24.05.05 09:57
Оценка:
Здравствуйте, eao197, Вы писали:

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


E>Так ведь:


ssm>>
ssm>>void readFile3(const char *fileName)
ssm>>{
ssm>>    std::ifstream file(fileName, std::ios::binary);
ssm>>    string str;

ssm>>    file.seekg( 0, ios_base::end);
ssm>>    std::ifstream::pos_type len = file.tellg();
ssm>>    file.seekg( 0);
ssm>>    str.resize( len);
ssm>>    file.read( (char*)str.data(), len);   //(*)

ssm>>    std::cout << " " << str.length() << " ";
ssm>>}
ssm>>


E>некорректен.



а так?
    file.read( &str[0], len);   //(*)
Re[4]: отчет DevPartner
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 10:04
Оценка:
Здравствуйте, zelyony, Вы писали:

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


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


E>>Так ведь:


ssm>>>
ssm>>>void readFile3(const char *fileName)
ssm>>>{
ssm>>>    std::ifstream file(fileName, std::ios::binary);
ssm>>>    string str;

ssm>>>    file.seekg( 0, ios_base::end);
ssm>>>    std::ifstream::pos_type len = file.tellg();
ssm>>>    file.seekg( 0);
ssm>>>    str.resize( len);
ssm>>>    file.read( (char*)str.data(), len);   //(*)

ssm>>>    std::cout << " " << str.length() << " ";
ssm>>>}
ssm>>>


E>>некорректен.



Z>а так?

Z>
Z>    file.read( &str[0], len);   //(*)
Z>


Имхо, это тоже самое.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: еще один отчет
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 24.05.05 10:41
Оценка:
Тоже решил пойти по следам ssm.

Собрал вот такую программку:
#include <iostream>
#include <iterator>
#include <fstream>
#include <algorithm>
#include <functional>
#include <string>
#include <sstream>
#include <ctime>
#include <map>

using namespace std;

void readFile1(const char *fileName)
{
    std::ifstream ifs(fileName, std::ios::binary);
    std::string s;
    copy(istreambuf_iterator<char>(ifs), istreambuf_iterator<char>(), back_inserter(s));

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

void readFile2(const char *fileName)
{
    std::ifstream file(fileName, std::ios::binary);
    std::string str;

    std::copy(
        istream_iterator<char>(file), 
        istream_iterator<char>(), 
        insert_iterator<string>(str,str.begin()));

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

void readFile4(const char *fileName)
{
    string s;
    ifstream inp(fileName, std::ios::binary);
    getline(inp, s, '\0');

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

void readFile5(const char *fileName)
{
    string s;
    ifstream is(fileName, std::ios::binary);

    //
    // attempt to grow string buffer to match file size,
    // this doesn't always work...
    s.reserve(is.rdbuf()->in_avail());
    char c;
    while(is.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);
    }

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

void readFile6(const char *fileName)
{
    typedef std::istream_iterator<char> IIC;

    std::ifstream file(fileName, std::ios::binary);    

    file.seekg( 0, std::ios_base::end);
    std::fstream::pos_type size = file.tellg();
    file.seekg( 0);
    
    std::string str_file;
    str_file.reserve(size);
    std::copy(IIC(file), IIC(), std::back_inserter(str_file));

    std::cout << " " << str_file.length() << " ";

}

void readFile7(const char *fileName)
{
    std::ifstream in(fileName, std::ios::binary);
    ostringstream out;           
    out << in.rdbuf(); 

    string s;
    out.str().swap(s); 

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

typedef void (*PF)(const char*);
typedef std::map< std::string, PF > func_map_t;

struct    meter_t
    :    public std::unary_function< func_map_t::value_type, void >
    {
        int    m_argc;
        char **    m_argv;

        meter_t( int argc, char ** argv )
            :    m_argc( argc )
            ,    m_argv( argv )
            {}

        result_type
        operator()( argument_type a )
            {
                std::cout << a.first << " " << std::flush;

                std::clock_t start = std::clock();

                for( int i = 1; i < m_argc; ++i )
                    (*a.second)( m_argv[ i ] );

                std::clock_t finish = std::clock();

                std::cout << "duration: " << double( finish - start ) / CLOCKS_PER_SEC
                        << std::endl;
            }
    };

int main( int argc, char ** argv ) 
{ 
    func_map_t readers;
    readers[ "readFile1" ] = &readFile1;
    readers[ "readFile2" ] = &readFile2;
    readers[ "readFile4" ] = &readFile4;
    readers[ "readFile5" ] = &readFile5;
    readers[ "readFile6" ] = &readFile6;
    readers[ "readFile7" ] = &readFile7;
    
  std::for_each(
        readers.begin(), readers.end(),
        meter_t( argc, argv ) );
}


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

На Visual С++ 7.1 получил:
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 22.92
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 36.843
readFile4  6  5  3  3  5 duration: 0.047
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 25.655
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 35.42
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.984


На Borland C++ 5.6:
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 17.203
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 50.234
readFile4  6  5  3  3  5 duration: 0.016
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 34.938
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 62.593
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 23.282


На MinGW C++ (3.2.3 20030504-1):
readFile1  50996600  46676172  40532459  40480453  36657475 duration: 34.9
readFile2  49827578  45636872  39624753  39557524  35823658 duration: 62.562
readFile4  6  5  3  3  5 duration: 0.157
readFile5  50996600  46676172  40532459  40480453  36657475 duration: 55.983
readFile6  49827578  45636872  39624753  39557524  35823658 duration: 59.307
readFile7  50996600  46676172  40532459  40480453  36657475 duration: 14.47


Еще под Linux-ом осталось подсчитать.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: весь файл из ifstream >> string
От: Valodzka Беларусь  
Дата: 24.05.05 10:53
Оценка:
Здравствуйте, Erop, Вы писали:

E>А что случится, если в файле встретится байт '\0'?

E>Я так понимаю, что такой байт в строчку добавлять нельзя?

Точно где это написано не помню, но по стандарту std::string должен корректно обрабатывать любые символы, в том числе '\0'
Не перебивайте меня, когда я вас перебиваю
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[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

Так вот...
А все ли решения работают?
От: 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[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...
Пока на собственное сообщение не было ответов, его можно удалить.