Strategies to Enhance IOStream Performance
Most C programmers prefer the printf/scanf functions when coding in C , citing their superior interface. However, IOStreams often face performance concerns.
Buffering Optimization
Increasing the buffer size enhances performance by reducing HDD hits and system calls. This can be achieved by accessing the underlying streambuf and modifying its buffer:
char Buffer[N]; std::ifstream file("file.txt"); file.rdbuf()->pubsetbuf(Buffer, N);
Locale Handling
Locales can introduce performance overhead due to complex operations like character conversion and filtering. Consider using the default C locale, designed for uniformity and minimal conversions.
Synchronization
Synchronizing with stdio does not appear to improve performance. However, it's possible to access a global setting using std::ios_base::sync_with_stdio.
Measurements and Results
Performance results vary significantly depending on the implementation and platform. Some users have reported faster C IOStreams, while others have experienced slower performance.
Benchmarking Code
For those interested in running their own benchmarks, here's a sample code:
template <typename Func> double benchmark(Func f, size_t iterations) { f(); timeval a, b; gettimeofday(&a, 0); for (; iterations--;) { f(); } gettimeofday(&b, 0); return (b.tv_sec * (unsigned int)1e6 + b.tv_usec) - (a.tv_sec * (unsigned int)1e6 + a.tv_usec); } struct CRead { CRead(char const* filename): _filename(filename) {} void operator()() { FILE* file = fopen(_filename, "r"); int count = 0; while (fscanf(file,"%s", _buffer) == 1) { ++count; } fclose(file); } char const* _filename; char _buffer[1024]; }; struct CppRead { CppRead(char const* filename): _filename(filename), _buffer() {} enum { BufferSize = 16184 }; void operator()() { std::ifstream file(_filename, std::ifstream::in); file.rdbuf()->pubsetbuf(_buffer, BufferSize); int count = 0; std::string s; while (file >> s) { ++count; } } char const* _filename; char _buffer[BufferSize]; }; int main(int argc, char* argv[]) { size_t iterations = 1; if (argc > 1) { iterations = atoi(argv[1]); } char const* oldLocale = setlocale(LC_ALL,"C"); if (strcmp(oldLocale, "C") != 0) { std::cout << "Replaced old locale '" << oldLocale << "' by 'C'\n"; } char const* filename = "largefile.txt"; CRead cread(filename); CppRead cppread(filename); bool oldSyncSetting = std::ios_base::sync_with_stdio(false); double ctime = benchmark(cread, iterations); double cpptime = benchmark(cppread, iterations); std::ios_base::sync_with_stdio(oldSyncSetting); std::cout << "C : " << ctime << "\n" "C++: " << cpptime << "\n"; return 0; }
The above is the detailed content of Is C IOStreams Always Slower Than printf/scanf?. For more information, please follow other related articles on the PHP Chinese website!