由于memcpy,C ++ ifstream :: read变慢
最近我决定优化一些我正在做的文件阅读,因为正如大家所说,将大量数据读取到缓冲区然后使用它比使用大量小读取更快。 而且我的代码现在肯定快得多,但是在进行一些分析之后,似乎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更快。 另外,使用Windows ReadFile只会带来一些微不足道的优势(我查看了代码,而且fread基本上是ReadFile的一个包装)。 看起来我终究会转向fread。
男人写一个基准测试这个东西真的很困惑。
结论:使用<cstdio>
比<fstream>
更快。 fstream较慢的原因是因为c ++流有自己的内部缓冲区。 这会导致您在读/写时进行额外的复制,并且此复制占了fstream所花费的整个额外时间。 更令人震惊的是,花费的额外时间比实际读取文件所用的时间更长。
如果你想加快文件的速度,I / OI建议你使用好的'ol' <cstdio>
因为它可以大幅超越C ++。
我能否以某种方式告诉ifstream将我需要的大小直接缓冲到缓冲区中?
是的,这是pubsetbuf()的用途。
但是,如果你关心的是如何复制读取文件,请考虑内存映射,boost有一个可移植的实现。
已经多次证明,读取数据的最快方法是在Linux系统上使用mmap()
。 我不知道Windows。 然而,它肯定会没有这种缓冲。
fopen()
, fread()
, fwrite()
( FILE*
)有些更高级别,可能会产生缓冲区,而open()
, read()
, write()
函数是低级别的,来自Os内核。
上一篇: C++ ifstream::read slow due to memcpy
下一篇: Python with Numpy/Scipy vs. Pure C++ for Big Data Analysis