2010-07-16 32 views
4

我在這裏得到了一些奇怪的性能結果,我希望stackoverflow.com上的人可以對此有所瞭解!爲什麼fseeko()比巨型文件更快而不是小文件?

我的目標是一個程序,我可以用它來測試是否尋求大的比小的更貴求的......

首先,我創建了兩個文件由dd'ing的/ dev /零到單獨的文件..一種是1 MB,另一種是9.8gb ...然後我寫了這個代碼:在整個範圍內的文件

#define _LARGE_FILE_API 
#define _FILE_OFFSET_BITS 64 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main(int argc, char* argv[]) 
{ 
    struct stat64 fileInfo; 
    stat64(argv[1], &fileInfo); 

    FILE* inFile = fopen(argv[1], "r"); 

    for(int i = 0; i < 1000000; i++) 
    { 
     double seekFrac = ((double)(random() % 100))/((double)100); 

     unsigned long long seekOffset = (unsigned long long)(seekFrac * fileInfo.st_size); 

     fseeko(inFile, seekOffset, SEEK_SET); 
    } 

    fclose(inFile); 
} 

基本上,這個代碼百萬隨機尋找。當我運行該下的時候,我得到這樣的結果對於小文件:

[[email protected] ~]# time ./seeker ./smallfile 

real 0m1.863s 
user 0m0.504s 
sys 0m1.358s 

當我運行它針對9.8演出文件,我得到的結果是這樣的:

[[email protected] ~]# time ./seeker ./bigfile 

real 0m0.670s 
user 0m0.337s 
sys 0m0.333s 

我撞上了每個文件幾十次,結果是一致的。在大文件中搜索的速度是在小文件中搜索的兩倍多。爲什麼?

+0

您的搜索分佈非常稀疏:它們都是文件大小的整數百分比值(0-99)。嘗試將間隔降低到0.1%左右,然後再降低0.01%等,看看是否有任何差異。 – casablanca 2010-07-16 17:27:09

回答

15

您不測量磁盤性能,您正在測量fseek設置指針並返回所需的時間。

如果你想測試真正的IO,我建議你從你正在尋找的位置讀取文件。

+0

哇...好吧,我在查找單個字符後添加了getc()調用。現在,在大文件中尋找只比在小文件中尋找要貴一些。是否有一些優化,其中多個後續的搜索總結,並在下一個IO之前實際完成?哇... – dicroce 2010-07-16 17:27:47

+4

seek()只是一個暗示你打算從下一個地方讀取的操作系統。操作系統有一個複雜的調度機制來移動磁盤磁頭,使所有用戶的總行程時間最小化。由於你的閱讀與其他人交錯,所以直到最後一刻,當操作系統(而不是你的程序,操作系統!)準備進行閱讀時,這是毫無意義的。所以操作系統會在你的腦海中保持你的尋求位置,但是直到它真正地物理讀取數據時纔會執行它。 – 2010-07-16 17:38:38

0

我會假設它與fseeko的實施有關。

fseek的手冊頁表明它只是「設置指定流的文件位置指示符」。由於設置一個整數應該獨立於文件大小,所以可能存在一個「優化」,它會在小文件而不是大文件的fseek之後執行自動讀取(並緩存結果信息)。

相關問題