2013-07-22 46 views
0

使用標誌FILE_FLAG_IO_BUFFERING讀取一組沒有緩衝的文件(跳過文件緩存)應該比正常讀取(不使用此標誌)更快。更快的原因是'無緩衝'機制會跳過系統文件緩存並直接讀入應用程序的緩衝區。
應用程序運行在冷環境中(磁盤碎片整理,機器重新啓動後),以便系統文件緩存在運行前不會與相關文件一起緩存。
這是關於這些API和標誌的msdn文檔。
FILE_FLAG_IO_BUFFERING減慢同步讀取操作

但是,我體驗到完全不同的表現行爲。在使用FILE_FLAG_IO_BUFFERING標誌創建文件句柄之後,我一個接一個地同步讀取一組文件。讀取這組文件所需的時間是29秒。如果我沒有使用這個標誌(如果在文件緩存沒有保存相關文件的情況下在應用程序的低溫運行中)正常讀取,則所需時間大約爲24秒。

詳細
文件總數:1939年
文件總大小(所有的總和):57 MB
隨着FLAG_IO_NO_BUFFERING:29秒(時間讀取)
沒有FLAG_IO_NO_BUFFERING:24秒(花時間閱讀)

這裏是實現讀取代碼:

DWORD ReadFiles(std::vector<std::string> &filePathNameVectorRef) 
{ 
    long totalBytesRead = 0;  
    for(all file in filePathNameVectorRef) 
     totalBytesRead += Read_Synchronous(file);   
    return totalBytesRead; 
} 

DWORD Read_Synchronous(const char * filePathName) 
{ 
    DWORD accessMode = GENERIC_READ; 
    DWORD shareMode = 0; 
    DWORD createDisposition = OPEN_EXISTING; 
    DWORD flags = FILE_FLAG_NO_BUFFERING; 
    HANDLE handle = INVALID_HANDLE_VALUE; 
    DWORD fileSize; 
    DWORD bytesRead = 0; 
    DWORD bytesToRead = 0; 
    LARGE_INTEGER li; 
    char * buffer; 
    BOOL success = false; 


    handle = CreateFile(filePathName, accessMode, shareMode, NULL, createDisposition, flags, NULL); 
    if(handle == INVALID_HANDLE_VALUE) 
      return 0; 

    GetFileSizeEx(handle, &li); 
    fileSize = (DWORD)li.QuadPart; 

    bytesToRead = (fileSize/g_bytesPerPhysicalSector)*g_bytesPerPhysicalSector; 
    buffer = static_cast<char *>(VirtualAlloc(0, bytesToRead, MEM_COMMIT, PAGE_READWRITE)); 

    if(buffer == NULL) 
     goto RETURN; 

    success = ReadFile(handle, buffer, bytesToRead, &bytesRead, NULL); 

    if(!success){ 
     fprintf(stdout, "\n Error occured: %d", GetLastError()); 
     return 0; 
    } 

    free(buffer); 

RETURN: 
    CloseHandle(handle); 
    return bytesRead; 
} 

PL輕鬆地分享你的想法,因爲你認爲這段代碼的運行速度比不使用FILE_FLAG_NO_BUFFERING時慢。謝謝。

+0

如果你總是按順序閱讀,你可以嘗試添加'FILE_FLAG_SEQUENTIAL_SCAN'標誌,看看它是否有幫助。 –

+0

當你跳過緩存時,你也會跳過它擁有的那個美妙的選項,能夠將整個軌道讀入緩存。這是非常便宜的,因爲驅動器頭已經位於正確的位置,這是免費的數據。 –

回答

0

我希望你測量的是打開和關閉文件的時間。有相當多的文件。您應該能夠在大約一秒鐘內從磁盤讀取57MB。所以開銷似乎是文件開放而不是閱讀。您應該使用較少但較大的文件再試一次。創建20個100MB文件並讀取這些文件。看起來至少在你的系統上,使用FILE_FLAG_NO_BUFFERING打開文件比沒有打開文件要慢。

無論如何,不​​要指望FILE_FLAG_NO_BUFFERING加快速度。將數據從文件句柄的緩衝區複製到緩衝區所花費的時間與將數據從磁盤中移出的時間相比是微不足道的。