使用istream和FILE*操作的getline的性能差异
Performance difference of getline operating with istream and FILE*
我正在尝试逐行比较读取文件的性能。第一种情况是字符串和 istream 的 getline,第二种情况是 char* 和 FILE* 的 getline。我想知道:
- 为什么第一种情况这么慢?
- 是否有可能使C++片段更快?
考虑以下输出(ifstream 优先(:
Lines count: 10628126
ifstream getline: 43.2684
Lines count: 10628126
fopen getline: 1.06217
文件*优先:
Lines count: 10628126
fopen getline: 1.96065
Lines count: 10628126
ifstream getline: 43.0428
我用于测试的代码:
#include <fstream>
#include <iostream>
#include <string>
#include <sys/time.h>
#include <stdio.h>
using namespace std;
double gettime()
{
double result = 0;
struct timeval tv = {0};
struct timezone tz = {0};
gettimeofday(&tv, &tz);
result = tv.tv_sec + (1.0 * tv.tv_usec / 1000000);
return result;
}
void read_cpp(const char * filename)
{
ifstream ifile(filename);
string line;
unsigned int i = 0;
while(getline(ifile, line)) i++;
cout << "Lines count: " << i << endl;
}
void read_c(const char * filename)
{
FILE * ifile = fopen(filename, "r");
size_t linesz = 4096+1;
char * line = new char[linesz];
unsigned int i = 0;
while(getline(&line, &linesz, ifile) > 0) i++;
delete[] line;
cout << "Lines count: " << i << endl;
fclose(ifile);
}
int main(int argc, char * argv[])
{
double tmstart;
tmstart = gettime();
read_cpp(argv[1]);
cout << "ifstream getline: " << (gettime() - tmstart) << endl;
tmstart = gettime();
read_c(argv[1]);
cout << "fopen getline: " << (gettime() - tmstart) << endl;
}
附言我试图交换read_cpp和read_c几乎没有区别。
更新
看起来@Galik和@geza无法使用 g++ 编译器重现该问题,所以我检查了 linux 环境中的代码,C和C++实现之间几乎没有区别。所以这似乎是一个环境问题。最初,我使用Mac OS X和默认的C++编译器测量时间,该编译器clang
(对我来说很惊讶(:
$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
但所有这些事情从未发生在真正的g++
:
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ...
Thread model: posix
gcc version 4.9.2 (Debian 4.9.2-10)
对不起,给大家带来不便。
UPDATE2
我发现相关主题 clang++ fstreams 比 g++ 慢 10 倍。作者还面临着由 clang 编译的代码的性能下降。要解决此问题,可以使用不同的stdlib
实现(-stdlib=stdlibc++
(而不是默认的实现(-stdlib=libc++
(。在这种情况下,clang
将显示弃用警告:
clang: warning: libstdc++ is deprecated; move to libc++ [-Wdeprecated]
但是性能会好得多(即使没有优化(:
Lines count: 10628126
fopen getline: 1.02899
Lines count: 10628126
ifstream getline: 1.67594
c++ 版本执行了更多的边界检查、区域设置解释和 iostream 状态管理。它非常强大。
c版本是极简主义的,而且更脆。
安全和实用是有代价的。
这个代价就是时间。
更新:
c readline 期望使用 malloc 和 free,而不是 new 和 delete。
这是更正后的版本:
#include <cstdlib>
#include <cstdio>
#include <iostream>
void read_c(const char * filename)
{
FILE * ifile = fopen(filename, "r");
size_t linesz = 0;
char * line = nullptr;
unsigned int i = 0;
while(getline(&line, &linesz, ifile) > 0) i++;
free(line);
std::cout << "Lines count: " << i << std::endl;
fclose(ifile);
}
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- Seg Fault Issue C++ (file IO / getline)
- OpenMP阵列性能较差
- 递归列出所有目录中的C++与Python与Ruby的性能
- 大小相等但成员数量不同的结构之间的性能差异
- 为什么constexpr的性能比正常表达式差
- 当用户键入分隔符时,停止getline()输入
- 在类中使用随机生成器时出现性能问题
- 在main()之外初始化std::vector会导致性能下降(多线程)
- getline() 的原型/库是什么;
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 如何在 c++ 中使用 ',' 作为 getline 分隔符
- 错误:调用'getline'没有匹配函数
- 如何在 c++ 中使用 getline 从文件中读取字符串?
- 海湾合作委员会 ARM 性能下降
- GCC 和 Clang 代码性能的巨大差异
- 在容量内调整矢量大小时的性能影响
- 将 getline() 与文件一起使用
- 使用istream和FILE*操作的getline的性能差异
- fstream中多个get()和单个getline()之间的理论性能差异