最近我决定优化我正在做的一些文件读取,因为正如大家所说,将大量数据读取到缓冲区然后使用它比使用大量小读取更快。而且我的代码现在肯定要快得多,但在进行一些分析之后,似乎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的包装器)。看起来我毕竟会转向恐惧。
编写一个实际上正确测试这些东西的基准测试令人困惑。
结论:使用<cstdio>
比<fstream>
更快。 fstream较慢的原因是因为c ++流有自己的内部缓冲区。每当您进行读/写操作时,这会导致额外的复制,并且此复制会占用fstream所需的整个额外时间。更令人震惊的是,所花费的额外时间比实际读取文件所花费的时间更长。
答案 0 :(得分:5)
我可以告诉ifstream直接缓冲我需要的大小 进入我的缓冲区?
是的,这是pubsetbuf()的用途。
但是,如果您关心的是复制读取文件,也请考虑内存映射,boost有portable implementation。
答案 1 :(得分:3)
如果你想加快文件I / O,我建议你使用好的'<cstdio>
,因为它可以大大优于C ++。
答案 2 :(得分:1)
已经多次证明,在Linux系统上读取数据的最快方式是mmap()
。关于Windows,我不知道。但是,如果没有这种缓冲肯定会这样做。
fopen()
,fread()
,fwrite()
(FILE*
)略高一些,可能会产生缓冲,而open()
,read()
,write()
函数是低级别的,你可能拥有的唯一缓冲区来自Os内核。