我想讀取大型CSV文件並將其存儲到地圖中。我從閱讀文件開始,看看需要多長時間來處理。這是我的循環:在C++中讀取大型CSV文件(〜4GB)
while(!gFile.eof()){
gFile >> data;
}
它需要我〜35分鐘來處理包含3500萬行和6列的csv文件。有什麼辦法可以加快速度嗎?對於SO來說很新,所以如果不能正確地問道歉,
我想讀取大型CSV文件並將其存儲到地圖中。我從閱讀文件開始,看看需要多長時間來處理。這是我的循環:在C++中讀取大型CSV文件(〜4GB)
while(!gFile.eof()){
gFile >> data;
}
它需要我〜35分鐘來處理包含3500萬行和6列的csv文件。有什麼辦法可以加快速度嗎?對於SO來說很新,所以如果不能正確地問道歉,
背景
文件是流設備或概念。讀取文件的最有效的用法是保持數據流(流動)。對於每個事務都有一個開銷。數據傳輸越大,開銷的影響就越小。所以,目標是保持數據流動。
內存比文件訪問速度更快
搜索內存比搜索一個文件快許多倍。因此,搜索「單詞」或分隔符將比逐字符地查找文件字符以查找分隔符更快。
方法1:通過線
使用std::getline
線比使用operator>>
快得多。儘管輸入代碼可能會讀取一塊數據;您只執行一個事務來讀取一個記錄而不是每列一個事務。請記住,保持數據流動和搜索內存的速度更快。
方法2:塊讀
在保持流動的流的精神,讀存儲器塊到一個緩衝器(大緩衝液)。處理來自緩衝區的數據。這比逐行讀取更有效,因爲您可以使用一個事務讀取多行數據,從而減少事務開銷。
一個需要注意的是,你可能有一個記錄交叉緩衝區的邊界,所以你需要想出一個算法來處理這個問題。執行懲罰很小,並且每個事務只發生一次(考慮事務的這部分開銷)。
方法3:多個線程
在保持數據流的精神,你可以創建多個線程。一個線程負責或將數據讀入緩衝區,而另一個線程處理來自緩衝區的數據。保持數據流動,這項技術會有更好的運氣。
方法4:雙緩衝&多個線程
這需要上述方法3和增加了多個緩衝器。讀線程可以填充一個緩衝區,然後開始填充第二個緩衝區。數據處理線程將在處理數據之前等待第一個緩衝區填滿。該技術用於更好地將讀取數據的速度與處理數據的速度相匹配。
方法5:內存映射文件
隨着內存映射文件,操作系統處理文件的需求讀入內存。您必須編寫的代碼越少,但是您對文件讀入內存時的控制權也不盡如人意。這比逐場閱讀還要快。
Id避免多個線程,除非Im計算綁定,這往往是一堆額外的不必要的複雜性。Win32'CreateFile' +'ReadFile'或者nix'open' +'read'實際上並不難,並且可以以全磁盤速度讀取(甚至比內存映射更好,因爲您可以依次告訴操作系統您的讀取),somthing C++甚至沒有「專用」線程。對於簡單的CSV等,甚至可以保持SSD的潛在讀取速度而無需線程(每秒幾百MB)。 –
Downvoters:請添加評論解釋你downvote。我親自實施了這些技術,並在處理大小超過1GB的數據文件時發現了顯着的性能提升。 –
讓我們從瓶頸開始吧。
解碼數據
商店希望你已經事先想過這個地圖是沒有性病地圖都是線程安全的。
內存速度
的內存
我很肯定有一些圖書館明確爲此目的。也就是說,35分鐘聽起來有點過長。你正在執行多少其他處理?確保你啓用了優化! – tambre
如果你一遍又一遍地重複寫同一個變量,目前還不清楚爲什麼需要這麼長時間。複製文件需要多長時間? – tadman
[將整個ASCII文件讀入C++ std :: string]可能重複(https://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring) – smac89