C++ ifstream::由于memcpy,读取速度慢
C++ ifstream::read slow due to memcpy
最近我决定优化我正在做的一些文件读取,因为正如大家所说,将大量数据读取到缓冲区然后使用它比使用大量小读取更快。而且我的代码现在肯定快得多,但是在进行了一些分析之后,memcpy似乎占用了大量时间。
我的代码的要点是...
ifstream file("some huge file");
char buffer[0x1000000];
for (yada yada) {
int size = some arbitrary size usually around a megabyte;
file.read(buffer, size);
//Do stuff with buffer
}
我正在使用Visual Studio 11,在分析我的代码后,它说ifstream::read()
最终调用从内部缓冲区复制到我的缓冲区xsgetn()
。此操作占用了80%以上的时间!排在第二位的是uflow()
,它占据了10%的时间。
有什么方法可以绕过这种复制吗?我可以以某种方式告诉ifstream
将我需要的大小直接缓冲到缓冲区中吗?C 型FILE*
是否也使用这样的内部缓冲区?
更新:由于人们告诉我使用cstdio...我已经做了一个基准测试。
编辑:不幸的是,旧代码充满了失败(它甚至没有读取整个文件!你可以在这里看到它:http://pastebin.com/4dGEQ6S7
这是我的新基准:
const int MAX = 0x10000;
char buf[MAX];
string fpath = "largefile";
int main() {
{
clock_t start = clock();
ifstream file(fpath, ios::binary);
while (!file.eof()) {
file.read(buf, MAX);
}
clock_t end = clock();
cout << end-start << endl;
}
{
clock_t start = clock();
FILE* file = fopen(fpath.c_str(), "rb");
setvbuf(file, NULL, _IOFBF, 1024);
while (!feof(file)) {
fread(buf, 0x1, MAX, file);
}
fclose(file);
clock_t end = clock();
cout << end-start << endl;
}
{
clock_t start = clock();
HANDLE file = CreateFile(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL);
while (true) {
DWORD used;
ReadFile(file, buf, MAX, &used, NULL);
if (used < MAX) break;
}
CloseHandle(file);
clock_t end = clock();
cout << end-start << endl;
}
system("PAUSE");
}
时间是:
185
80
78
井。。。看起来使用 C 风格的 fread 比 ifstream::read 更快。同样,使用窗口ReadFile只提供了可以忽略不计的轻微优势(我查看了代码,fread基本上是ReadFile的包装器)。看来我终究还是要改用恐惧了。
伙计,编写一个实际正确测试这些东西的基准测试是令人困惑的。
结论:使用<cstdio>
比<fstream>
快。fstream 较慢的原因是 c++ 流有自己的内部缓冲区。这会导致您在读取/写入时进行额外的复制,并且此复制占用了 fstream 所花费的全部额外时间。更令人震惊的是,花费的额外时间比实际读取文件所需的时间要长。
我可以以某种方式告诉ifstream直接缓冲我需要的大小吗 进入我的缓冲区?
是的,这就是pubsetbuf()的用途。
但是,如果您担心复制读取文件,请考虑内存映射,boost具有可移植的实现。
加快文件I/O的速度,我建议你使用好的老<cstdio>
,因为它可以大大优于C++。
已经多次证明,读取数据的最快方法是在 Linux 系统上mmap()
。我不知道Windows。但是,它肯定不会有这种缓冲。
fopen()
、fread()
、fwrite()
(FILE*
)是更高级别的,可能会诱导一个缓冲区,而open()
、read()
、write()
函数是低级的,你唯一可能拥有的缓冲区来自操作系统内核。
- 如何提高文件的读取速度?
- CUDA Shuffle指导减少速度慢于减少共享记忆
- 使用boost.lockfree队列比使用静音速度慢
- QT 5.7 串口读取速度很慢
- 如何在 Ubuntu 上提高我的程序磁盘读取速度
- 提升文件系统的速度慢得令人难以置信
- Winsock C++ - Java 连接速度慢
- Qt自定义树模型显示正确,但有缺陷且速度慢
- C++线程化的应用程序比非线程化的运行速度慢
- 函数调用速度慢得令人痛苦
- gcc std::unordered_map 实施速度慢吗?如果是这样 - 为什么
- 返回元素的速度比通过引用和修改发送元素的速度慢
- A* 寻路速度慢
- 流网络摄像头的速度慢,无法"detectMultiScale"
- 相同的功能?使用 GMP(C++) 时运行速度慢约 10 倍
- C++ 多线程处理速度慢
- C++ ifstream::由于memcpy,读取速度慢
- 运行时间比较 - 类似的代码运行速度慢 4 倍
- 大桌子的快速排序速度慢得出奇
- 在c++中重写这个python函数似乎会使其运行速度慢很多.这合理吗