【发布时间】:2016-03-10 02:20:21
【问题描述】:
这里是我的项目配置:vs2013,win32,Debug。
我想知道对于不同的文件大小,3种文件读取方式哪个会更快。它们是c++风格的fstream,c风格的文件读写和内存映射。
但执行后,这是我的结果:
文件大小 1225284
fstream 时间 47
c文件指针时间0
内存映射时间0文件大小 14856192
fstream 时间 15
c文件指针时间0
内存映射时间 47文件大小 97198080
fstream 时间 16
c文件指针时间0
内存映射时间 265文件大小 1259530844
fstream 时间 31
c文件指针时间16
内存映射时间 11138
似乎对于流和FILE*读取,读取文件所需的时间不会随着文件大小的增加而增加。但是对于内存映射,这是真的。这种现象很奇怪。
因为在我看来,对于大文件,内存映射会更快。
这是我的代码:
string ifile = "M:/Thesis/FileReadCmp/1.txt";
string os = "M:/Thesis/FileReadCmp/new_cmp1.txt";
int page_size = 2 * 1024 * 64 * 1024;//128M
for (int j = 0; j < 100; ++j){
os[os.size() - 5] = '1' + j;
ofstream o(os);
for (int i = 0; i < 4; ++i){
ifile[ifile.size() - 5] = '1' + i;
ifstream in(ifile);
in.seekg(0, ios::end);
o << "File Size " << in.tellg() << endl;
o << endl;
in.close();
//using fstream to read file
long long st = GetTickCount();
in.open(ifile);
char c;
while (in >> c){
;
}
in.close();
long long et = GetTickCount();
o << "fstream time " << et - st << endl;
//using FILE* to read file
st = GetTickCount();
FILE* cpf = fopen(ifile.c_str(), "r");
char cc = fgetc(cpf);
while (cc != EOF)
{
cc = fgetc(cpf);
}
fclose(cpf);
et = GetTickCount();
o << "c file pointer time " << et - st << endl;
//using memory mapping to read file
const char* pc = ifile.c_str();
st = GetTickCount();
HANDLE hFile = CreateFile(pc, GENERIC_WRITE | GENERIC_READ, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
int file_size = GetFileSize(hFile, NULL);
HANDLE hFileMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE,
TEXT("SharedData"));
if (hFileMap == NULL){
// if no such object,create a file mapping object
hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0, 0, TEXT("SharedData"));
}
int rem_file_size = file_size;
int offset = 0;
while (rem_file_size > page_size){
PVOID pvFileView = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, offset, page_size);
char* asc_dex = (char*)pvFileView;
for (int i = 0; i < page_size; ++i){//, c = 0++c
char c = asc_dex[i];
}
//UnmapViewOfFile(pvFileView);
offset += page_size;
rem_file_size -= page_size;
}
PVOID pvFileView = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, offset, rem_file_size);
char* asc_dex = (char*)pvFileView;
for (int i = 0; i < rem_file_size; ++i){//, c = 0++c
char c = asc_dex[i];
}
UnmapViewOfFile(pvFileView);
CloseHandle(hFileMap);
CloseHandle(hFile);
et = GetTickCount();
o << "memory mapping time " << et - st << endl;
o << endl;
}
}
【问题讨论】:
-
为什么要单独映射每个页面?
-
因为1GB大的文件,我无法将文件作为一个整体进行映射。最让我困惑的是使用stream和FILE*@immibis的读取速度
-
我已经删除了 UnmapViewOfFile(pvFileView);在循环内。@immibis
-
哎呀,我没有注意到你有 128MB 的页面 - 我假设 page_size 是页面的大小(只有 4kB)。对于 128MB 的“页面”,映射每个页面的开销应该不是问题。
-
我认为
UnmapViewOfFile应该在循环内;否则就是泄漏,不是吗?
标签: c++ file stream memory-mapping