2017-02-18 36 views
-3

在C++中寫入和讀取混合數據類型(即無符號整數,double,uint64_t,字符串)的有效方法。高效地在C++中讀寫混合數據類型 - 11

我需要在磁盤上寫入和讀取包含混合數據類型的數據。我用下面的方法寫數據。然而,它變得非常緩慢。

fstream myFile; 
myFile.open("myFile", ios::binary, ios::out); 
double x; //with appropriate initialization 
myFile<<x; 
int y; 
myFile<<y; 
uint64_t z; 
myFile<<z; 
string myString; 
myFile<<myString; 

但是,對於大小爲20 GB的大數據,這種方法的效率非常低。有人可以請建議我如何可以快速讀取和寫入混合數據類型在C++

+2

如果你開始分析20個字節的數據,你應該從基礎知識開始,就如何有效地完成這項任務進行一些研究。你有可能幫助你的同事嗎? –

+0

@LightnessRacesinOrbit不幸的是沒有 –

+1

然後,請原諒我這麼說,看起來你和你的團隊不適合這項任務。你是如何揹負它的? –

回答

1

我認爲你需要確定的第一件事是你的程序實際上是慢。

這是什麼意思?當然,你認爲速度很慢,但速度緩慢是因爲你的特定程序效率低下,還是速度很慢,因爲將20千兆字節的數據寫入磁盤本身就是一項耗時的操作?

所以我要做的第一件事就是在你的硬盤上運行一些基準測試來確定它的原始速度(以兆字節每秒或者其他)。有商業應用程序可以執行此操作,或者您可以使用內置實用程序(如Unix或Mac上的dd),以便大致瞭解您的特定硬盤驅動器讀取或寫入20千兆字節的虛擬數據所需的時間:

dd if=/dev/zero of=junk.bin bs=1024 count=20971520 

dd if=junk.bin of=/dev/zero bs=1024 

如果dd(或其他)能夠將數據顯著比你的程序能更快傳遞,再有就是房間的計劃,以改善。另一方面,如果dd的速度沒有比你的程序速度快得多,那麼除了購買更快的硬盤驅動器(或者SSD或RAM驅動器或其他產品)外,沒有什麼可以做的了。

假設上面的測試確實表明您的程序效率低於它,我會嘗試的第一件事是用等效的實現替換您的C++ iostream調用,而該實現使用C fopen()/fread()/fwrite()/fclose() API調用。一些C++ iostream實現是known to be somewhat inefficient,但(簡單的)C I/O API不太可能無效。如果沒有別的,比較C++和C版本的性能會讓你確認或否認你的C++庫的iostream實現是一個瓶頸。

如果即使C API沒有爲您提供所需的速度,接下來我要看的是將您的文件格式更改爲易於讀取或寫入的文件;例如,假設您有足夠的內存,可以使用mmap()將大塊虛擬地址空間與文件的內容相關聯,然後只讀取/寫入文件內容,就好像它是RAM一樣。 (這可能會或可能不會讓事情變得更快,這取決於您訪問數據的方式)。

如果一切都失敗了,最後要做的就是減少需要讀取或寫入的數據量。是否有部分數據可以單獨存儲,以便您不需要每次都讀取和寫入它們?有沒有數據可以更緊湊地存儲(例如,數據中常用的字符串可以存儲爲整數代碼而不是字符串)?如果您在寫入數據之前使用zlib壓縮數據,以便寫入的數據更少?您看起來在您的示例中編寫的數據看起來可能適合壓縮,可能會將您的20GB文件減少到5GB文件左右。等等