我正在写一个延迟敏感的应用程序,它在初始化时读取一个文本文件。 我已经分析并重新编写了所有的algorithm,使得我的执行时间的85%
boost::interprocess::file_mapping file(Path, read_only); boost::interprocess::mapped_region data(file, read_only);
我正在Windows上写这个 – 有没有更快的方法将文件映射到内存? 可移植性不是一个问题。
你可以使用Win32的本地函数,但是我认为你不会节省很多,因为boost不会增加额外的开销:
OFSTRUCT ofStruct; ofStruct.cBytes=sizeof (OFSTRUCT); HANDLE file=(HANDLE)OpenFile(fileName, &ofStruct, OF_READ); if (file==INVALID_HANDLE_VALUE) handle errors else { HANDLE map=CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, 0); if (map==INVALID_HANDLE_VALUE) handle errors else { const char *p=(const char *)MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0)); if (p) { // enjoy using p to read access file contents. } // close all that handles now... }
我会建议放弃文件映射的想法。
调频是一个复杂的构造,并增加了一些开销。 普通的高速缓存读取也涉及与物理设备的非平凡的交互。 你可以做无缓冲的读取。 可能接下来要问的是你究竟想要什么样的IO – 文件有多大? 它是连续的吗? 它在网络上吗? 你有硬件的选择,还是在客户的机器上?
如果文件很小,只需打开并使用标准的Win32 CreateFile()/ ReadFile()API将它们读入内存。
如果您按顺序使用每个文件(或者可以按照您的方式排列代码),则应该指定FILE_FLAG_SEQUENTIAL_SCAN。 这是文件/缓存子系统积极预读的提示。 对于小文件,可能会在首次调用ReadFile()之前将文件读入缓存中。
编辑 :按要求,这是一个片段,说明使用Win32 API读取文件的内容到字节的向量:
void ReadFileIntoBuffer( const std::wstring& fileName, std::vector< uint8_t >& output ) { HANDLE hFile( INVALID_HANDLE_VALUE ); try { // Open the file. hFile = CreateFile( filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); if( INVALID_HANDLE_VALUE != hFile ) throw std::runtime_error( "Failed to open file." ); // Fetch size LARGE_INTEGER fileSize; if( !GetFileSizeEx( hFile, &fileSize ) ); throw std::runtime_error( "GetFileSizeEx() failed." ); // Resize output buffer. output.resize( fileSize.LowPart ); // Read the file contents. ULONG bytesRead; if( !ReadFile( hFile, &output[0], fileSize.LowPart, &bytesRead, NULL ) ) throw std::runtime_error( "ReadFile() failed." ); // Recover resources. CloseHandle( hFile ); } catch( std::exception& ) { // Dump the error. std::cout << e.what() << " GetLastError() = " << GetLastError() << std::endl; // Recover resources. if( INVALID_HANDLE_VALUE != hFile ) CloseHandle( hFile ); throw; } }