Вопрос
Ввод-вывод файлов C++ сложнее, чем ввод-вывод файлов C.Итак, в C++ полезно или нет создание новой библиотеки для файлового ввода-вывода?Я имею в виду <fstream>
Может ли кто-нибудь сказать, есть ли какие-либо преимущества в вводе-выводе файлов C++?
Решение
Мнение
Я не знаю ни одного реального проекта, использующего потоки C++.Они слишком медленны и сложны в использовании.Есть несколько новых библиотек, таких как ФастФормат и Способствовать росту версия, которая претендует на лучшую, о них была статья в последнем журнале ACCU Overload.Лично я использую библиотеку c FILE последние 15 лет или около того на C++ и пока не вижу причин менять ее.
Скорость
Вот небольшая тестовая программа (я быстро ее составляю), чтобы показать основную проблему со скоростью:
#include <stdio.h>
#include <time.h>
#include<iostream>
#include<fstream>
using namespace std;
int main( int argc, const char* argv[] )
{
const int max = 1000000;
const char* teststr = "example";
int start = time(0);
FILE* file = fopen( "example1", "w" );
for( int i = 0; i < max; i++ )
{
fprintf( file, "%s:%d\n", teststr, i );
}
fclose( file );
int end = time(0);
printf( "C FILE: %ds\n", end-start );
start = time(0);
ofstream outdata;
outdata.open("example2.dat");
for( int i = 0; i < max; i++ )
{
outdata << teststr << ":" << i << endl;
}
outdata.close();
end = time(0);
printf( "C++ Streams: %ds\n", end-start );
return 0;
}
И результаты на моем ПК:
C FILE: 5s
C++ Streams: 260s
Process returned 0 (0x0) execution time : 265.282 s
Press any key to continue.
Как мы видим, этот простой пример работает в 52 раза медленнее.Я надеюсь, что есть способы сделать это быстрее!
ПРИМЕЧАНИЕ: изменение endl на ' ' в моем примере улучшило потоки C++, сделав его всего в 3 раза медленнее, чем потоки FILE* (спасибо половина) могут быть способы сделать это быстрее.
Сложность в использовании
Я не могу утверждать, что printf() не является кратким, но он более гибок (IMO) и его проще понять, как только вы преодолеете начальный WTF для макрокодов.
double pi = 3.14285714;
cout << "pi = " << setprecision(5) << pi << '\n';
printf( "%.5f\n", pi );
cout << "pi = " << fixed << showpos << setprecision(3) << pi << '\n';
printf( "%+.3f\n", pi );
cout << "pi = " << scientific << noshowpos << pi<< '\n';
printf( "%e\n", pi );
Вопрос
Да, возможно, существует потребность в лучшей библиотеке C++, многие так считают. ФастФормат что это за библиотека, покажет только время.
Дэйв
Другие советы
Устранение переполнения буфера кажется мне большой победой для C++.
Пожалуйста, взгляните на
http://www.ddj.com/cpp/184403651
тогда вы предпочтете ввод-вывод C++, чем ввод-вывод C.
Короче говоря, C предпочтительнее, если вы знаете размер данных до чтения или записи, а также для скорости.C++ предпочтительнее, если вы не знаете размер данных и для эффективного кода.
В ответ на ответ Дэвида Аллана Финча я исправил ошибку в его коде тестирования (он очищал поток в версии C++ после каждой отдельной строки) и перезапустил тест:
Цикл C++ теперь выглядит так:
start = time(0);
{
ofstream outdata("example2.txt");
for( int i = 0; i < max; i++ )
{
outdata << teststr << ":" << i << "\n"; // note, \n instead of endl
}
}
end = time(0);
Я запускаю 10000000 итераций (в 10 раз больше, чем в исходном коде, потому что в противном случае цифры слишком малы для Time () паршивое разрешение, чтобы дать нам что -то значимое)), а выход:
G++ 4.1.2:
C FILE: 4s
C++ Streams: 6s
MSVC9.0:
C FILE: 10s
C++ Streams: 23s
(обратите внимание, версия MSVC запускалась на моем ноутбуке со значительно более медленным жестким диском)
Но это дает нам разницу в производительности в 1,5-2,3 раза в зависимости от реализации.и другие внешние факторы.
Различия в производительности между форматированием потоков ввода-вывода в стиле printf()/fwrite и форматированием потоков ввода-вывода C++ во многом зависят от реализации.Некоторые реализации (например, визуальный C++) строят свои потоки ввода-вывода поверх объектов FILE *, и это имеет тенденцию увеличивать сложность их реализации во время выполнения.Однако обратите внимание, что для реализации библиотеки таким способом не было особых ограничений.
По моему мнению, преимущества ввода-вывода C++ заключаются в следующем:
- Типовая безопасность, как уже говорилось ранее.
- Гибкость реализации.Код может быть написан для выполнения определенного форматирования или ввода данных в общий объект ostream или istream или из него.Затем приложение может вызвать этот код с любым производным объектом потока.Если код, который я написал и протестировал для файла, теперь необходимо применить к сокету, последовательному порту или какому-либо другому внутреннему потоку, вы можете создать реализацию потока, специфичную для такого типа ввода-вывода.Расширение ввода-вывода в стиле C таким способом даже близко невозможно.
- Гибкость в настройках локали:подход C, использующий единую глобальную локаль, на мой взгляд, серьезно ошибочен.У меня были случаи, когда я вызывал код библиотеки (DLL), который менял глобальные настройки локали под моим кодом и полностью испортил мой вывод.Поток C++ позволяет вам внедрить() любую локаль в объект потока.
std::ifstream и std::ofstream уже находятся в библиотеке stl.Вам не обязательно создавать свой собственный.
Основное преимущество заключается в том, что все выходные и входные данные являются типобезопасными.
C и C++ — два разных языка.Файл C++ io требует некоторого времени, чтобы привыкнуть к нему, но как только вы начнете использовать алгоритмы, исключения и т. д., они, как правило, встанут на свои места очень естественным образом.
Всякий раз, когда мне нужно ввести/выдать выходные данные в файле на C++, я просто использую две строки.
freopen("input.txt","r",stdin); // for input from file
freopen("output.txt","w",stdout);// for output from file
Теперь вы можете сканировать переменные, как обычно, с консоли, и все, что вы печатаете в качестве вывода, будет отображаться в файле output.txt.
Поэтому я не думаю, что файловый ввод-вывод в C++ — это сложно, это проще, чем в C.
Много.Недостатки тоже.Подробности см. в разделе Часто задаваемые вопросы по языку C++.Суммируя:типобезопасность и определяемые пользователем типы.