增强 IOStream 性能的策略
大多数 C 程序员在用 C 进行编码时更喜欢 printf/scanf 函数,因为它们具有优越的接口。然而,IOStreams 经常面临性能问题。
缓冲优化
增加缓冲区大小可以通过减少 HDD 命中和系统调用来增强性能。这可以通过访问底层 Streambuf 并修改其缓冲区来实现:
char Buffer[N]; std::ifstream file("file.txt"); file.rdbuf()->pubsetbuf(Buffer, N);
区域设置处理
由于字符转换等复杂操作,区域设置可能会带来性能开销过滤。考虑使用默认的 C 语言环境,旨在实现一致性和最小化转换。
同步
与 stdio 同步似乎不会提高性能。但是,可以使用 std::ios_base::sync_with_stdio 访问全局设置。
测量和结果
性能结果根据实现和平台的不同而有很大差异。一些用户报告 C IOStream 速度更快,而其他用户则遇到性能较慢的情况。
基准测试代码
对于那些有兴趣运行自己的基准测试的人,这里有一个示例代码:
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; }
以上是C IOStreams 总是比 printf/scanf 慢吗?的详细内容。更多信息请关注PHP中文网其他相关文章!