C++ 写文件使用API和内存映射比较

比较写文件速度: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接口快很多:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值