比较写文件速度:windows的API接口和内存映射,详见下面代码:
#include <wtypes.h>
#include <windows.h>
#include <stdio.h>
#include <cstdint>
#include<string>
using namespace std;
#define EPOCHFILETIME (116444736000000000UL)
// 获取系统的当前时间,单位微秒(us)
int64_t GetSysTimeMicros()
{
FILETIME ft;
LARGE_INTEGER li;
int64_t tt = 0;
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
// 从1970年1月1日0:0:0:000到现在的微秒数(UTC时间)
tt = (li.QuadPart - EPOCHFILETIME) / 10;
return tt;
}
struct stu {
double d;
int i;
char c;
};
stu s;
//内存映射方式写文件
BOOL FileMapping(const char* filename)
{
HANDLE hFile = CreateFile(filename, GENERIC_WRITE | GENERIC_READ, 0, NULL
, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//创建文件,与普通打开文件相同,可使用fopen
if (hFile == INVALID_HANDLE_VALUE)
{
printf("File could not be opened.");
return FALSE;
}
//int64_t nTime1End = GetSysTimeMicros();
DWORD dwFileSize = sizeof(stu);
//int64_t nTime2Begin = GetSysTimeMicros();
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0,dwFileSize*10000, NULL);//创建内存映射文件
//int64_t nTime2End = GetSysTimeMicros();
if (hFileMap == NULL) {
CloseHandle(hFile);
return FALSE;
}
//int64_t nTime4Begin = GetSysTimeMicros();
PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);//可以理解为获取文件在硬盘上的地址
//int64_t nTime4End = GetSysTimeMicros();
if (pvFile == NULL) {
CloseHandle(hFileMap);
CloseHandle(hFile);
return FALSE;
}
//int64_t nTime5Begin = GetSysTimeMicros();
PSTR pchAnsi = (PSTR)pvFile;
int i = 0;
while(i < 10000)
{
memcpy(pchAnsi + i * dwFileSize, (char*)& s, dwFileSize);//内存拷贝
i++;
}
//int64_t nTime5End = GetSysTimeMicros();
stu temp = *(stu*)pchAnsi;
//通过验证,下面3句代码耗时最严重的
//int64_t nTime6Begin = GetSysTimeMicros();
UnmapViewOfFile(pvFile);
CloseHandle(hFileMap);
CloseHandle(hFile);
//int64_t nTime6End = GetSysTimeMicros();
return TRUE;
}
//API接口写文件
BOOL WindowAPIOpFile(const char *filename) {
FILE* fp;
if ( !(fp = fopen(filename, "wb+")) ) {
return false;
}
int i = 0;
while (i < 10000)
{
fwrite((void*)(&s), sizeof(struct stu), 1, fp);
i++;
}
fclose(fp);
return true;
}
int main() {
s.i = 1;
s.c = 'a';
s.d = 1.25000;
system("del 01test01.dat");
system("del 02test01.dat");
//内存映射,写文件
int64_t nFileMappingBeginTime = GetSysTimeMicros();
char ch[1024] = "01test01.dat";
FileMapping(ch);
int64_t nFileMappingEndTime = GetSysTimeMicros();
printf("FileMapping,beigin=%I64d,end=%I64d,time=%I64d\n", nFileMappingBeginTime, nFileMappingEndTime, nFileMappingEndTime- nFileMappingBeginTime);
//windows 写文件结构
int64_t nFileWindowAPIBeginTime = GetSysTimeMicros();
char ch2[1024] = "02test01.dat";
WindowAPIOpFile(ch2);
int64_t nFileWindowAPIEndTime = GetSysTimeMicros();
printf("FileWindowAPI,beigin=%I64d,end=%I64d,time=%I64d\n", nFileWindowAPIBeginTime, nFileWindowAPIEndTime, nFileWindowAPIEndTime - nFileWindowAPIBeginTime);
}
通过比较后,写入数据量越多,内存映射写文件速度更快,详见下面验证结果:
写入1000条记录耗时:
写入1万条记录耗时:
一次性写入一个大缓存,比如一次性写入256MB
内存映射比API接口快很多: