许多stackoverflow答案涉及如何从磁盘中啜饮文件,您可以根据文件大小预先分配内存。
但是什么是在stdin中啜饮的最快方法(例如,当一个大文件通过管道进入你的程序时)?
如果这是最快的解决方案,我很乐意进入一个向量(后来总是可以转换为std :: string)。
答案 0 :(得分:2)
将未格式化的数据读入内存的最快方法是使用未格式化的读取例程。例如,fstream :: read()。什么都不会打败它。
小心!有些人声称通过使用操作系统级例程(如read())可以看到性能提升。如果你试试这个,你会得到极大的性能下降。
EDIT。对上述陈述的一些解释。降级的原因是内核调用。每次读取都是内核调用,因此除非您准确读取最佳数据缓冲区的大小,否则将会引发更多内核调用或不太理想的读取。虽然您可以通过实验确定最佳读取大小,但C运行时已经为您完成了此操作。 fread()和未格式化的流读取已经过优化,因此无论读取块有多大,都可以保证以最佳方式调用内核。
答案 1 :(得分:0)
令我惊讶的是,老式的,几乎像c的代码似乎是clang和gcc中最快的代码:
{
vector<char> cin_str;
// 64k buffer seems sufficient
std::streamsize buffer_sz = 65536;
vector<char> buffer(buffer_sz);
cin_str.reserve(buffer_sz);
auto rdbuf = cin.rdbuf();
while (auto cnt_char = rdbuf->sgetn(buffer.data(), buffer_sz))
cin_str.insert(cin_str.end(), buffer.data(), buffer.data() + cnt_char);
}
使用istream::read()
和istream::gcount()
同样快,但需要一些额外的代码......
令人惊讶的是,使用istreambuf_iterator
(未格式化输入的迭代器)变得更慢,更慢:&gt;对于某些测试文件来说是3倍,即使在关闭与stdio同步之后也是如此。< / p>
{
std::ios_base::sync_with_stdio(false) ;
vector<char> cin_str;
// 64k
std::streamsize buffer_sz = 65536;
cin_str.reserve(buffer_sz);
std::istreambuf_iterator<char> iit (std::cin.rdbuf()); // stdin iterator
std::istreambuf_iterator<char> eos; // end-of-range iterator
std::copy(iit, eos, std::back_inserter(cin_str));
return cin_str;
}
即使为vector
缓冲区保留空间(而不仅仅是分配给它),也是如此。
另一个令人惊讶的是,即使具有非常适度的缓冲区大小(64 kb),也能看到(接近)最大速度。 vector
只是一个非常有效的重新分配策略。
(http://insanecoding.blogspot.in/2011/11/reading-in-entire-file-at-once-in-c.html)似乎表明这种方法与c ++(gcc / clang)一样快,而切换到cstdio并没有提供进一步的收益(但显然使得代码甚至更丑!)。
@BenVoigt指出,如果我们明智地预先分配必要的空间,那么读取数据可以由sgetn()
/ istream::read()
放置到位:
{
std::ios_base::sync_with_stdio(false) ;
// 64k
std::streamsize buffer_sz = 65536;
vector<char> cin_str(buffer_sz);
std::streamsize cin_str_data_end = 0U;
auto rdbuf = cin.rdbuf();
while (auto cnt_char = rdbuf->sgetn(cin_str_data_end + cin_str.data(), buffer_sz))
{
cin_str_data_end += cnt_char;
cin_str.resize(cin_str_data_end + buffer_sz);
}
cin_str.resize(cin_str_data_end);
return cin_str;
}
在测试中,这导致没有进一步的加速可能因为这个代码主导1)i / o 2)系统调用开销3)向量内存分配
有更快的方法吗?来自boost的内存映射文件?