我有一个50gb的文件,我想读。
将从50gb文件中读取x指令。它们将按顺序排列,但位置不可预测。每条指令将读取1个字节。
总读数占<文件总大小的0.0000001%,可能总共大约100个字节。
现在我正在使用带偏移的seekg来执行此操作,但它正在采取>有时3秒。
在这种情况下,内存映射文件会加快读取速度吗?如果我没有50gb的ram,那么记忆映射文件是否有意义?
我还能做些什么来加快速度吗?
以下是一些代码,需要大约2秒才能为我运行(我将其调整为300次读取以使其花费更长时间):
#include <iostream>
#include <fstream>
#include <set>
#include <cstdlib>
using namespace std;
int main() {
ifstream in("E:/t.dat", ifstream::binary);
in.rdbuf()->pubsetbuf(0, 1);
set<long long> S;
srand(time(NULL));
for(int i=0;i<300;i++){
S.insert((long long)(rand()%50000000)*1000ll);
}
long long offset = 0;
in.seekg(0,ios::beg);
int sum = 0;
for(set<long long>::iterator it = S.begin(); it!=S.end(); it++){
long long toseek = *it - offset;
while(toseek > 2000000000){
in.seekg(2000000000,ios::cur);
toseek -= 2000000000;
offset += 2000000000;
}
in.seekg(toseek,ios::cur);
offset += toseek;
char c;
in.read(&c,1);
offset++;
sum += (int)c;
}
cout<<sum<<endl;
}
答案 0 :(得分:4)
在这种情况下,内存映射文件是否会加快读取速度?
如果不了解有关文件访问模式和操作系统的更多详细信息,则很难回答。你最好的选择是试一试并衡量。但是对于非内存映射的情况,我建议在文件上禁用缓冲setvbuf(3)
以避免读取任何额外数据(或者使用open(2)
/ {{3的原始Unix文件API }} / lseek(2)
/ read(2)
)。您还可以使用close(2)
向操作系统提供有关如何缓冲文件页面的提示 - 在您的情况下,您可能希望通过POSIX_FADV_RANDOM
告诉它您将访问文件页面随机,可能禁用预读行为,这将导致不必要的I / O.
如果我没有50g的内存,那么对内存映射文件是否有意义?
确实如此,只要你有足够的地址空间 - 这对于32位进程根本不起作用,但在64位进程中它会没问题。操作系统将为整个文件范围分配虚拟地址空间,但由于需求分页,在您实际读取或写入任何给定页面之前,它不会向其提交任何物理内存。如果您碰巧触摸的页面数量超过了物理内存中可以容纳的数量,那么寻呼机将只会找出最近最少使用的页面。
答案 1 :(得分:0)
现在我正在使用带偏移的seekg来执行此操作,但它正在采取&gt;有时3秒。
发布代码。
在这种情况下,内存映射文件会加快读取速度吗?如果我没有50g的ram,那么记忆映射文件是否有意义?
可能不是,而且它可能不会表现得更好,可能会无比恶化,因为你会导致英雄规模的交换。
我还能做些什么来加快速度吗?
发布代码。