C和C++文件读取性能的比较
Comparison of C and C++ file read performance
我最近需要逐行读取一个不太重要的文件,为了提高性能,我决定遵循我得到的一些建议,即fstream
s比C风格的I/O慢得多。然而,尽管我尽了最大的努力,我还是没能再现同样的戏剧性差异(~25%,这是很大的,但并不疯狂)。我还试用了fscanf
,发现它慢了一个幅度。
我的问题是,是什么导致了隐藏的性能差异,为什么fscanf
非常糟糕?
以下是我的代码(使用TDM GCC 5.1.0编译):
struct file
{
file(const char* str, const char* mode)
: fp(fopen(str, mode)){}
~file(){fclose(fp);}
FILE* fp;
};
constexpr size_t bufsize = 256;
auto readWord(int pos, char*& word, char* const buf)
{
for(; buf[pos] != 'n'; ++word, ++pos)
{
if(pos == bufsize)
return 0;
*word = buf[pos];
}
*word = ' ';
return pos + 1;
}
void readFileC()
{
file in{"inC.txt", "r"};
char buf[bufsize];
char word[40];
char* pw = word;
int sz = fread(buf, 1, bufsize, in.fp);
for(; sz == bufsize; sz = fread(buf, 1, bufsize, in.fp))
{
for(auto nextPos = readWord(0, pw, buf); (nextPos = readWord(nextPos, pw, buf));)
{
//use word here
pw = word;
}
}
for(auto nextPos = readWord(0, pw, buf); nextPos < sz; nextPos = readWord(nextPos, pw, buf))
{
//use word here
pw = word;
}
}
void readFileCline()
{
file in{"inCline.txt", "r"};
char word[40];
while(fscanf(in.fp, "%s", word) != EOF);
//use word here
}
void readFileCpp()
{
ifstream in{"inCpp.txt"};
string word;
while(getline(in, word));
//use word here
}
int main()
{
static constexpr int runs = 1;
auto countC = 0;
for(int i = 0; i < runs; ++i)
{
auto start = steady_clock::now();
readFileC();
auto dur = steady_clock::now() - start;
countC += duration_cast<milliseconds>(dur).count();
}
cout << "countC: " << countC << endl;
auto countCline = 0;
for(int i = 0; i < runs; ++i)
{
auto start = steady_clock::now();
readFileCline();
auto dur = steady_clock::now() - start;
countCline += duration_cast<milliseconds>(dur).count();
}
cout << "countCline: " << countCline << endl;
auto countCpp = 0;
for(int i = 0; i < runs; ++i)
{
auto start = steady_clock::now();
readFileCpp();
auto dur = steady_clock::now() - start;
countCpp += duration_cast<milliseconds>(dur).count();
}
cout << "countCpp: " << countCpp << endl;
}
用1070KB大小的文件运行,结果如下:
countC: 7
countCline: 61
countCpp: 9
编辑:三个测试用例现在读取不同的文件并运行一次。结果正好是读取同一文件20次的1/20。countC
始终优于countCpp
,即使我翻转了执行它们的顺序
fscanf
必须解析格式字符串参数,寻找所有可能的%
符号,并对其进行解释,以及宽度指定符、转义符、表达式等。它必须一次遍历格式参数或多或少一个字符,处理一大组潜在的格式。即使你的格式像"%s"
一样简单,与其他技术相比,它仍然需要大量的开销,这些技术只需抓取一堆字节,几乎没有解释/转换等开销。
相关文章:
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 性能比较:f(std::string&&) vs f(T&&)
- C++ STL 双链表性能比较
- C++和Java的字符串循环性能比较
- Python和C 性能比较
- unordered_set与链接列表之间的性能比较
- 超线程性能比较
- 性能比较:strstr()与std::string::find()
- OpenCV:C++和C性能比较
- 多维阵列与平面阵列 - 性能比较
- 赛通VS C++性能比较
- STL排序在字符串矢量与字符串指针矢量上的性能比较
- C++ 虚函数与成员函数指针(性能比较)
- 随机生成的排序数组:搜索性能比较
- C++内存分配机制性能比较(tcmalloc与jemalloc)
- 嵌套循环内外变量声明的性能比较
- 预先知道参数时的性能比较
- `std::vector`与`std::queue`的性能比较
- Android上Java库和c++ dll的性能比较
- c++中简单迭代list over map的性能比较