1

I'm writing a latency-sensitive app which reads a text file upon initialisation. I have profiled and re-written all my algorithms such that 85% of my execution time is from the lines:

boost::interprocess::file_mapping file(Path, read_only);
boost::interprocess::mapped_region data(file, read_only);

I am writing this on windows- is there any faster way to map a file into memory? Portability is not a concern.

4

3 回答 3

3

您可以只使用 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...
  }
于 2012-12-16T22:22:34.320 回答
1

如果文件很小,只需使用标准 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;
    }
}
于 2012-12-16T22:49:50.037 回答
1

我建议放弃文件映射的想法。

FM 是一个复杂的结构,会增加一些开销。普通缓存读取还涉及与物理设备的重要交互。您可以进行无缓冲读取。可能接下来要问的是你真正想要什么样的 IO - 文件有多大?是顺序的吗?是在网络上吗?您可以选择硬件,还是在客户的机器上?

于 2012-12-16T22:28:41.960 回答