readfile1.cpp是使用内存映射文件读取文件,readfile2.cpp是普通ReadFile
readfile1.cpp代码
char buf[10001];
const char *env = getenv("DATA_DIR");
char wsp[255];
sprintf(wsp, "%s/demo.dbf", env);
//const char *wsp = "wan.log";
int a = GetTickCount();
HANDLE h = CreateFile(wsp, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE h2 = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL);
char *p = (char *)MapViewOfFile(h2, FILE_MAP_READ, 0, 0, 0);
for(int j = 0; j < 1000; j++)
{
for(int i = 0 ; i < 1000; i++)
{
memcpy(buf, p + i*10000, 10000);
}
}
printf("time used %d\n", GetTickCount() - a);
buf[10000] = 0;
//printf(buf);
UnmapViewOfFile(p);
CloseHandle(h2);
CloseHandle(h);
scanf("%s", buf);
return 0;
readfile2.cpp代码
char buf[10001];
const char *env = getenv("DATA_DIR");
char wsp[255];
sprintf(wsp, "%s/demo.dbf", env);
int a = GetTickCount();
ULONG r;
HANDLE h = CreateFile(wsp, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
for(int j = 0; j < 1000; j++)
{
for(int i = 0 ; i < 1000; i++)
{
SetFilePointer(h, 10000*i, 0, FILE_BEGIN);
ReadFile(h, buf, 10000, &r, 0);
}
}
printf("time used %d\n", GetTickCount() - a);
buf[10000] = 0;
CloseHandle(h);
scanf("%s", buf);
return 0;
性能对比
1,任务管理器中各项指标
2,速度对比
任务管理器中各项指标性能对比:随机访问时1比2快多了
2.1 如果把2中SetFilePointer注释掉
结论
1.频繁的SetFilePointer与ReadFile会非常费劲。就算SetFilePointer调用是多余的。
2.去掉SetFilePointer后与2原来io读取量对比可知,ReadFile其实本身就有缓存;
SetFilePointer会使ReadFile的缓存机制失去作用。
3.使用内存映射随机读取文件会比ReadFile快多了,但是顺序读取文件时ReadFile快(估计是内存映射机制有太多的页面错误,性能有损耗)
4.内存映射文件其实就是建立起虚拟内存与物理磁盘间的映射关系。访问建立起内存映射文件的虚拟内存时,如果那块文件没有装进内存,会引起缺页中断,自动把那部分文件装进内存以供访问。因此1的页面错误比2多很多。但是1的io读取量又比2少很多,推测是由缺页中断导致的io读取并没有在任务管理器体现。
5.用内存映射文件读文件,内存哪里去了?为何1跟2比他不比2占内存?看看1的缺页次数与2对比,多了2453次,在windows上默认一个页面就是4k大小,2453*4k大约就是9.5m其实大约就是10m,就是我实际读了这么多的文件,这解释了说明了1.其实内存映射文件不占内存,2.io量虽然在io读取字节里面看不出来,但是在缺页次数上面可以推算出来。