1

初期化時にテキストファイルを読み取るレイテンシーに敏感なアプリを書いています。実行時間の85%が次の行からのものになるように、すべてのアルゴリズムのプロファイルを作成して書き直しました。

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

私はこれをWindowsで書いています-ファイルをメモリにマップするより速い方法はありますか?移植性は問題ではありません。

4

3 に答える 3

3

Win32のネイティブ関数を使用することもできますが、ブーストによって多くのオーバーヘッドが追加されないため、多くを節約することはできないと思います。

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

ファイルマッピングのアイデアを捨てることをお勧めします。

FMは複雑な構造であり、いくらかのオーバーヘッドが追加されます。プレーンキャッシュ読み取りには、物理​​デバイスとの重要な相互作用も含まれます。バッファなしの読み取りを行うことができます。おそらく次に質問するのは、実際に必要なIOの種類です。ファイルのサイズはどれくらいですか。シーケンシャルですか?ネットワーク上にありますか?ハードウェアの選択肢はありますか、それともお客様のマシンにありますか?

于 2012-12-16T22:28:41.960 に答える
1

ファイルが小さい場合は、開いて、標準のWin32 CreateFile()/ ReadFile()APIを使用してメモリに読み込みます。

各ファイルを順番に使用する場合(または、そのようにコードを配置できる場合)、FILE_FLAG_SEQUENTIAL_SCANを指定する必要があります。これは、ファイル/キャッシングサブシステムが積極的に先読みするためのヒントです。小さなファイルの場合、ReadFile()の最初の呼び出しが発行される前に、ファイルがキャッシュに読み込まれることがあります。

編集:要求に応じて、Win32APIを使用してファイルの内容をバイトのベクトルに読み取る方法を示すスニペットを次に示します。

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 に答える