簡體   English   中英

讀取/寫入文本文件的最快方法,不包括特定字符串

[英]Fastest way to read / write text file, excluding specific string

我正在編寫一個程序,它讀取大的 (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();

但是,我確信有更好的解決方案。 實現這一目標最快可行的方法是什么?

這里有幾點:

  • substr創建一個新字符串,這對於簡單比較來說非常昂貴。 自 C++17 以來,您可以使用字符串視圖來避免創建新字符串。 另一種解決方案是使用與 position 和大小compare 從 C++20 開始,還有ends_with ,這里更簡單。
  • std::endl刷新效率低下的 output。 請考慮只使用'\n'代替。
  • getline在實踐中往往有點慢。 您可以讀取大塊並自己解析,同時盡可能避免復制。 寫塊也更有效率。 塊不需要太大以適合 CPU 的緩存(RAM 比緩存慢)。 例如, getline跳行效率不高,因為它復制了 memory 中的數據。使用塊,您可以直接搜索接下來的三個\n ,而無需任何寫入。 此操作可以使用 SIMD 指令輕松矢量化,因此速度非常快(編譯器應該能夠為您完成)。
  • currLine預留一些空間可能會導致小幅加速。
  • 可以嘗試並行化該算法,但它肯定不值得,因為處理應該是 IO 綁定(除非文件被緩存或您使用高性能 Nvme SSD)並且這並不容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM