使用内存映射文件来提高你程序的性能
本人在学习《WINDOWS核心编程》的时候对JEFFREY大师提到的一个小程序写了两个版本来比较性能,该程序的原始需求是这样的:对一个大文件进行倒序,也就是将一个文件头变成尾,尾变成头。
使用的方法有很多种,这里使用两个方法来比较,主要是突出使用内存映射文件好处;两种方法为:内存映射文件方法,I/O读写的缓存办法。
第一种办法是创建内存映射文件对象,然后将该对象映射到进程的地址空间中,再读取文件内容,然后倒序,再写入文件。
第二中方法是,将文件内容读入一个大的缓冲区,然后倒序,再写入文件,中间对原来的文件删除,然后重新写入。
程序编写如下
第一种方法,内存映射文件方式:
{
HANDLE hFile = CreateFile(pszPathName,GENERIC_WRITE|GENERIC_READ,0,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("File could not be opened.");
return FALSE;
}
DWORD dwFileSize = GetFileSize(hFile,NULL);
HANDLE hFileMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,
dwFileSize+sizeof(char),NULL);
if(hFileMap == NULL){
CloseHandle(hFile);
return FALSE;
}
PVOID pvFile = MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,0,0);
if(pvFile == NULL){
CloseHandle(hFileMap);
CloseHandle(hFile);
return FALSE;
}
PSTR pchAnsi = (PSTR)pvFile;
pchAnsi[dwFileSize/sizeof(char)]=0;
_strrev(pchAnsi);
pchAnsi = strchr(pchAnsi,'\n');
while(pchAnsi != NULL){
*pchAnsi++ ='\r';
*pchAnsi++ ='\n';
pchAnsi = strchr(pchAnsi,'\n');
}
UnmapViewOfFile(pvFile);
CloseHandle(hFileMap);
SetFilePointer(hFile,dwFileSize,NULL,FILE_BEGIN);
SetEndOfFile(hFile);//实际上不需要写入了。
CloseHandle(hFile);
return TRUE;
}
第二中方法,使用缓存的方式:
{
HANDLE hFile = CreateFile(pszPathName,GENERIC_WRITE|GENERIC_READ,0,NULL
,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("File could not be opened.");
return FALSE;
}
DWORD dwFileSize = GetFileSize(hFile,NULL);
//CloseHandle(hFile);
char *readBuf = new char[dwFileSize+1];
DWORD nRead = 0,nRet =0;
while(nRead<dwFileSize){
if(ReadFile(hFile,readBuf+nRead,dwFileSize-nRead,&nRet,NULL) ==TRUE)
{
nRead+= nRet;
}
else
{
printf("Can read the file!");
CloseHandle(hFile);
}
}
PSTR pchAnsi = (PSTR)readBuf;
pchAnsi[dwFileSize/sizeof(char)]=0;
_strrev(pchAnsi);
pchAnsi = strchr(pchAnsi,'\n');
while(pchAnsi != NULL){
*pchAnsi++ ='\r';
*pchAnsi++ ='\n';
pchAnsi = strchr(pchAnsi,'\n');
}
CloseHandle(hFile);
DeleteFile(pszPathName);
HANDLE hWriteFile = CreateFile(pszPathName,GENERIC_WRITE|GENERIC_READ,0,NULL
,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(hWriteFile,readBuf,dwFileSize,&nRet,NULL);
CloseHandle(hWriteFile);
delete readBuf;
return TRUE;
}
我运行了几次,比较结果如下:
文件大小(byte) | 1方法时间(ms) | 2方法时间(ms) |
25416 | 0 | 0 |
101664 | 0 | 0 |
406656 | 0 | 10 |
1219968 | 10 | 30 |
3202416 | 21 | 100 |
9607248 | 80 | 551 |
67250736 | 581 | 5568 |
本人测试机器的CPU是迅池1.5的笔记本,内存为712MB
通过上面的测试我们可以看到使用内存映射文件的好处,在文件内存越大这种优势就体现的越明显,其中主要的原因是:
内存映射文件直接将文件的地址映射到进程的地址空间中,那么操作文件就相当于在内存中操作一样,省去了读和写I/O的时间;第二种方式是必须这么做(READFILE,WRITEFILE),这个过程是很慢的。
使用内存映射文件来提高你程序的性能相关推荐
- Windows核心编程 第十七章 -内存映射文件(上)
第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...
- 《windows核心编程》 17章 内存映射文件
内存映射文件主要用于以下三种情况: 系统使用内存映射文件载入并运行exe和dll,这大量节省了页交换文件的空间以及应用程序的启动时间 开发人员可以使用内存映射文件来访问磁盘上的数据文件.这使得我们可以 ...
- Windows之内存映射文件
=====================Windows之内存映射文件===================== 几乎每个应用程序都要处理文件,但要处理好并不容易.应用程序到底是先应该打开文件.再读取 ...
- Windows核心编程——》第十七章 内存映射文件 (Memory-Mapped Files)
1.概览 (1)什么是内存映射文件 内存映射文件是由一个文件到一块内存的映射,使进程虚拟地址空间的某个区域与磁盘上某个文件的部分或全部内容的建立映射. 建立映射后,通过该区域可以直接对被映射的磁盘文件 ...
- 用内存映射文件实现进程间通信
使用内存映射文件的一般流程: 由于内存映射文件的一致性,即系统保证在同一文件映射对象的多个视图间保持一致.这可以作为进程通讯的基础,而且在Windows上,同一台机器上共享数据的最底层机制都是内存映射 ...
- windows笔记-内存映射文件
Windows提供了3种进行内存管理的方法: • 虚拟内存,最适合用来管理大型对象或结构数组. • 内存映射文件,最适合用来管理大型数据流(通常来自文件)以及在单个计算机上运行的多个进程之间共享数据. ...
- Java基础:JavaNIO 之 内存映射文件原理
1. 前言 最近研究Java中内存映射I/O.Java类库中的NIO中的内存映射文件MappedByteBuffer,相对于Java I/O是一个新的功能.特把适合用于处理大文件,在对大文件处理的时候 ...
- 内存映射文件——Windows核心编程学习手札之十七
内存映射文件 --Windows核心编程学习手札之十七 与虚拟内存一样,内存映射文件保留地址空间,并将物理存储器提交给该区域,差别在于所提交的物理存储器是磁盘上有文件存在的空间,而非系统的页文件,一旦 ...
- C#内存映射文件学习总结
C#内存映射文件学习 http://www.cnblogs.com/flyant/p/4443187.html 内存映射文件是由一个文件到进程地址空间的映射. C#提供了允许应用程序把文件映射到一个进 ...
最新文章
- 计算机绘画教案风车,中班美术教案《风车》
- linux7 设置dns,RHEL7.0 系列-设置IP地址、网关和DNS
- 符合skyline的3dml网络发布服务
- Spring经典面试题和答案
- Java程序Date类型比较
- 上传文件到阿里云OSS报错-Unable to execute HTTP request: You have no right to access this object because of buc
- C#基础12.1:Object类
- 从零开始搭二维激光SLAM --- 基于ceres的后端优化的代码实现
- 自动驾驶 6-3 几何横向控制 - Stanley Geometric Lateral Control - Stanley
- 使用 Java 编写 Apache APISIX 插件
- 百度文库文章提取器(下)
- winhttp 访问https_asp程序使用Microsoft.XMLHTTP对象请求https时出错,使用WinHttp.WinHttpRequest.5.1解决...
- ubuntn 常用命令和快捷键汇总
- 常用链接cg 和game
- python的sysfont_pygame.font.SysFont游戏文字交互
- 计算机usb显示不出来怎么办,U盘在电脑上显示不出来怎么办
- 多WLAN口路由器原理分析
- Can‘t checkout because of unmerged files You have to resolve all merge conflicts bef
- vue开发h5 公众号
- Dubbo (五) ---------监控中心