我正在撰寫一個程式,它讀取大(10Gb )文本檔案,以塊的形式結構化,如下所示:
@Some_header
ATCCTTTATTCGGTATCGGATATATTACGCGCGGGGGATATCGGGG
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:::::::::
@Some_header unfixable_error
ATTTATTTAGAGGAGACTTTTATTTACCCCCCCCGGGGGGATTTTA
FFFFFFF:::::::::::::::FFFFFFFFFFUUUUUUUFFUUFUU
@Some_header
ATTATTCCCCTTTTTATACCGGGGGGAAATTAGGGGGGGCCCCTTT
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
一個塊由@header、ATCG 序列、“ ”和另一個與 ATCG 序列長度相同的字串組成。一些@header 行在換行符之前有'unfixable_error'。我的程式必須通讀這些檔案并將所有塊(帶有 @header unfixable_error 的塊除外)寫入新檔案。
目前,我的方法是使用'getline()',如下所示:
std::ifstream inFile(inFileStr);
std::ofstream outFile(outFileStr);
std::string currLine;
while (getline(inFile, currLine)) {
if (currLine == " " || currLine.substr(currLine.length()-5, 5) != "error") {
outFile << currLine << std::endl;
}
else {
for (int i = 0; i < 3; i ) {
getline(inFile, currLine);
}
}
}
inFile.close();
outFile.close();
但是,我確信有更好的解決方案。實作這一目標的最快可行方法是什么?
uj5u.com熱心網友回復:
這里有幾點:
substr創建一個新字串,這對于簡單的比較來說是相當昂貴的。從 C 17 開始,您可以使用字串視圖來避免創建新字串。另一種解決方案是使用compare位置和大小。從 C 20 開始,這里還有ends_with一個更簡單的。std::endl重繪 低效的輸出。請考慮'\n'改為使用。getline在實踐中往往會有點慢。您可以閱讀大塊并自己決議它,同時盡可能避免復制。寫入塊也更有效。塊不需要太大以便適合 CPU 的快取(與快取相比,RAM 很慢)。例如,跳過行getline效率不高,因為它將資料復制到記憶體中。使用塊,您可以直接搜索接下來的三個\n而無需任何寫入。此操作可以使用 SIMD 指令輕松矢量化,因此速度非常快(編譯器應該能夠為您做到這一點)。- 預先保留一些空間
currLine可能會導致小幅加速。 - 可以嘗試并行化演算法,但它肯定不值得,因為處理應該是 IO 系結的(除非檔案被快取或者您使用高性能 Nvme SSD)而且這并不容易。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/511775.html
標籤:C 表现文件流
上一篇:Webhook接收器回應
