2013-10-16 96 views
-2

我的問題是:如何讀取文件超過50 MB 快速(即大約一秒鐘),使用C++或C程序...通過文件中讀取快速

什麼我感興趣的是文件,其中包含普通整數...

我已經排除了ifstream,導致它太慢,爲此目的(8-9秒)。

目前,我使用的fscanf,但儘管如此,它是非常非常慢(4秒)....

我100%確信文件的讀取方式的問題,而且我沒有I/O限制。

你能提出任何替代方案嗎?

編輯

文件格式:

1 2 41 2 1 5 1 2 ... (integers) 
+1

你想用它做什麼?文件的格式是什麼? – BoBTFish

+1

是什麼讓你覺得你不是I/O綁定的?你有分析過嗎? –

+0

啊,還沒有,但是如果你用3.5秒來劃分50MB,那真的沒什麼意義......另外,我已經在4臺不同的PC上測試了它...... – user2886385

回答

2

嘗試使用內存映射文件。嘗試使用Google搜索

CreateFileMapping 
MapViewOfFile 
+0

這不是一個真正的答案,它應該是一個評論。另外,(s?)他沒有說過哪個平臺正在使用。並非每個人都使用Windows!但無論如何,如果我理解正確,那並不真正「讀取」文件。它使它看起來像內存,但是你仍然需要將整個事情從磁盤上移到內存中來解析整數(儘管這可能會更快)。 – BoBTFish

+0

他。而我同時使用Win和Linux ...... – user2886385

1

要更快地讀入數據,必須減少讀取數量並增加讀取數據量。

假設最壞的情況下,硬盤驅動器的初始化對於每個讀命令:

  • 的盤片必須達到速度(需要時間)。
  • 操作系統讀取目錄結構。
  • 操作系統在目錄結構中搜索文件。
  • 該操作系統告訴硬盤驅動器從哪個扇區或盤片&扇區讀取 。
  • 硬盤驅動器等待扇區開始,然後從扇區開始讀取連續數據 。
  • 硬盤驅動器旋轉下來。

除了從該部門讀取的所有內容都被視爲開銷。開銷將用於讀取一個字節是讀取還是讀取10k。效率是保持驅動器旋轉,這意味着每個「讀取」命令讀取更多的數據。

的許多方法來優化這個:

  • 單個大緩衝器上 - 讀了大量的數據到一個單一的緩衝區和 解析緩衝區。
  • 雙緩衝或多重緩衝 - 使用多個緩衝區,所以一個 線程可以解析一個緩衝區,而另一個線程讀取數據到另一個緩衝區。
  • 內存映射文件 - 操作系統管理文件讀取,就好像它是 內存。

程序之外的其他方法:

  • 優化利用固定 記錄大小文件數據結構有效閱讀。
  • 減少文件中的碎片數量 - 瞄準硬盤驅動器上一個巨大的連續區域 。
1

爲什麼這個文件包含的內容很重要?讀一個54MB的文件花了半秒鐘這個非常快速和骯髒的標準C程序:

#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 

unsigned char *big_file = NULL; 
size_t length; 

int main(int argc, char **argv) 
{ 
    FILE *f; 
    clock_t start_time, end_time; 
    if (argc >= 2) 
    { 
     start_time = clock(); 
     f = fopen (argv[1], "rb"); 
     if (f) 
     { 
      fseek (f, 0, SEEK_END); 
      length = ftell(f); 
      fseek (f, 0, SEEK_SET); 
      big_file = (unsigned char *)malloc(length); 
      if (big_file) 
      { 
       if (fread (big_file, 1,length, f) == length) 
        printf ("successfully read %lu bytes\n", (unsigned long)length); 
       free (big_file); 
      } 
      fclose (f); 
     } 
     end_time = clock() - start_time; 
     printf ("this took %f second(s)\n", ((double)end_time)/CLOCKS_PER_SEC); 
    } 
} 

輸出:

successfully read 54721618 bytes 
this took 0.523000 second(s) 

被警告:在運行它第二次在相同文件返回此:

successfully read 54721618 bytes 
this took 0.037000 second(s) 

有了這個,你的問題可能需要改寫:「好了,所以我可以閱讀速度很快,但我需要對該數據做XXX「 - 如果」XXX「=」很多「,則可能會超過1秒時間分配內的0.477秒。

+0

實際上,這確實可以非常快......但是,我只需要在不到1秒的時間內讀取數據,處理所花費的時間幾乎可以忽略不計。 – user2886385

+0

@ user2886385:那麼你接受我的解決方案? – usr2564301