求问一个大文件读取时用映射方式读取时的有关问题
求问一个大文件读取时用映射方式读取时的问题
[size=14px]现在需要快速的读取文件一个大文件中的全部信息,网上查看了下,觉得通过映射方式相比cfile中的read等方式能达到较高的速度,因此通过映射方式进行了读取,但是发现第一次读取一个125M的文件并将数据添加至vector中差不多要900ms,但是当以后读取时只需30ms或者更少的时间,很神奇,而且我的程序是一个DLL程序,即使重新编译后再运行也是30ms,在电脑重新启动后第一次运行又将是900ms,然后接下去又是30ms。
针对以上情况,有如下问题:
1、 读取大文件时是否有更快的方法,文件的格式很简单,就是存储了同样的结构体的数据;
2、请问后续读取时30ms为什么能那么快?还是我程序没设置好,读取125M的文件本来就只需125M?
------解决方案--------------------
在文件大小相同的前提下:
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
------解决方案--------------------
估计是文件系统有cache。
------解决方案--------------------
差别的原因应该是cache,你这种固定格式的数据可以使用多线程文件读取,我试了下,读取速度效果还是很明显的。不用链表直接用数组效果更明显。
[size=14px]现在需要快速的读取文件一个大文件中的全部信息,网上查看了下,觉得通过映射方式相比cfile中的read等方式能达到较高的速度,因此通过映射方式进行了读取,但是发现第一次读取一个125M的文件并将数据添加至vector中差不多要900ms,但是当以后读取时只需30ms或者更少的时间,很神奇,而且我的程序是一个DLL程序,即使重新编译后再运行也是30ms,在电脑重新启动后第一次运行又将是900ms,然后接下去又是30ms。
针对以上情况,有如下问题:
1、 读取大文件时是否有更快的方法,文件的格式很简单,就是存储了同样的结构体的数据;
2、请问后续读取时30ms为什么能那么快?还是我程序没设置好,读取125M的文件本来就只需125M?
[/size]
DWORD dwFileSize=GetFileSize(hfile,NULL);
HANDLE hFileMap=CreateFileMapping(hfile,NULL,PAGE_READONLY,0,0,NULL);
PVOID pvFile = NULL;
STRUCT_IDX StructIdx(0,0,0,0) ;//一个类初始化
int BatchEventNum=dwFileSize/STRUCT_SIZE;
EventFile* pMapFile;
pvFile=MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,dwFileSize);
pMapFile=(BatchEventFile*)pvFile;
for (int i=0;i<BatchEventNum;i++)
{
nReadEventCnt++;
EventStructIdx.uchProductID=pMapFile->Events[i].uchID;
EventStructIdx.wLOtIDIdx=pMapFile->Events[i].wIdx;
EventStructIdx.FileIdx=fileidx +differ;
EventStructIdx.FilePosition=i*STRUCT_SIZE;
EventIdxList.push_back(BatchEventStructIdx);
}
UnmapViewOfFile(pvFile);
CloseHandle(hFileMap);
SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
CloseHandle(hfile);
------解决方案--------------------
在文件大小相同的前提下:
读刚读过的文件比头次读没读过的文件快
读转速快的硬盘上的文件比读转速慢的硬盘上的文件快
读没有磁盘碎片的文件比读有磁盘碎片的文件快
读文件不处理比边读边处理快
单线程从头到尾一次读文件比多线程分别读文件各部分快(非固态硬盘上)
读固态硬盘上的文件比读普通硬盘上的文件快
------解决方案--------------------
估计是文件系统有cache。
------解决方案--------------------
差别的原因应该是cache,你这种固定格式的数据可以使用多线程文件读取,我试了下,读取速度效果还是很明显的。不用链表直接用数组效果更明显。
// c or c++.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <typeinfo>
#include <windows.h>
#include <process.h>
#include <exception>
#include <fstream>
#include <vector>
using namespace std;
void generate_data();
void read_data();
void read_data2();
void thread_read_fun( void* pArguments);
struct BLOCK_DATA;
int _tmain(int argc, _TCHAR* argv[])
{
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
//generate_data();
//read_data();
read_data2();
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2-QPart1);
dfTim = dfMinus / dfFreq;
cout << dfTim << endl;
getchar();
return 0;
}
struct BLOCK_DATA
{
int a;
int b;
int c;
int d;
friend ostream& operator<< (ostream &os, BLOCK_DATA &bd);
};
ostream& operator<< (ostream &os, BLOCK_DATA &bd)
{
return os << bd.a << bd.b << bd.c << bd.d;
}
void generate_data()
{
cout << "begin" << endl;
fstream fs("F:\\test_data\\data", ios_base::binary
------解决方案--------------------
ios_base::out);
BLOCK_DATA d;
for (int i = 0; i < 10000000; ++i)
{
d.a = i + 1;
d.b = i + 2;
d.c = i + 3;
d.d = i + 4;
fs.write(reinterpret_cast<char *>(&d), sizeof(BLOCK_DATA));
}
fs.close();
cout << "end" << endl;
}
void read_data()
{
HANDLE hfile = CreateFile(_T("F:\\test_data\\data"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwFileSize = GetFileSize(hfile, NULL);
HANDLE hFileMap = CreateFileMapping(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
BLOCK_DATA bd ;//一个类初始化
int BatchEventNum = dwFileSize / sizeof(BLOCK_DATA);
vector<BLOCK_DATA> bdList(BatchEventNum);
BLOCK_DATA *pvFile = (BLOCK_DATA *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, dwFileSize);
for (int i=0; i < BatchEventNum; ++i)
{
bd = pvFile[i];
bdList.push_back(bd);
}
UnmapViewOfFile(pvFile);
CloseHandle(hFileMap);
SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
CloseHandle(hfile);
}
struct thread_data
{