2016-07-20 32 views
2

Ich habe große TXT-Dateien mit mehr als einer Million Zeilen und 7 Spalten von Fließkommazahlen pro Zeile. Die Spalten sind durch Leerzeichen getrennt.Wie kann die Lesegeschwindigkeit erhöht werden?

Derzeit importiere ich die Dateien, indem ich jede Zeile (getline) lese, die Zeile in einen Stream umwandle und dann die sieben Werte in Array-Variablen speichere (siehe mein minimales Beispiel). Dieser Vorgang ist jedoch ziemlich langsam und dauert etwa 10 Minuten für 3 Millionen Zeilen (500 MB). Dies entspricht 0,8 MB/s und ist wesentlich langsamer als das Schreiben der Dateien. Meine Festplatte ist SSD.

Können Sie mir Tipps geben, wie Sie die Effizienz des Codes verbessern können?

Bests, Fabian

C++

#include <iostream> 
#include <string> 
#include <sstream> 
#include <fstream> 

struct Container { double a, b, c, d, e, f, g; }; 

void read_my_file(std::ifstream &file, Container *&data) { 
    std::string line; 
    std::stringstream line_as_stream; 
    unsigned int column; 
    unsigned long int row; 

    data = new Container[300000]; //dynamically allocated because the 
            //length is usually a user input. 

    for (row = 0; row < 300000; row++) { 
     getline(file, line); 
     line_as_stream.str(line); 

     for (column = 0; column < 7; column++) { 
      line_as_stream >> data[row].a; 
      line_as_stream >> data[row].b; 
      line_as_stream >> data[row].c; 
      line_as_stream >> data[row].d; 
      line_as_stream >> data[row].e; 
      line_as_stream >> data[row].f; 
      line_as_stream >> data[row].g; 
     } 

     line_as_stream.clear(); 
    } 
} 

int main(void) { 
    Container *data = nullptr; 
    std::ifstream file; 

    file.open("./myfile.txt", std::ios::in); 
    read_my_file(file, data); 
    std::cout << data[2].b << "\n"; 

    file.close(); 

    return 0; 
} 
+2

Diese Antwort [Effizientes Lesen einer sehr großen Textdatei in C++] (http://stackoverflow.com/questions/26736742/efficiently-reading-a-y-large-text-file-in-c) scheint relevant . – rtur

+0

Warum versuchst du nicht nur 'file >> some_string;' direkt anstelle des ersten Kopierens in einen 'stringstream' zu verwenden? – Arunmu

+2

Takten Sie auch eine Version, optimierte Build Ihrer Anwendung? Oder ist es eine "Debug", nicht optimierte Version? – PaulMcKenzie

Antwort

-1

Ich denke, das liegt daran, dass C++ sind standardmäßig nicht Ströme gepuffert. In der ersten Schleife erhalten Sie also nur eine Zeile (da sie nicht gepuffert ist). Durch die Iteration greifen Sie immer wieder auf die Festplatte zu (was ziemlich langsam ist). you may want to look at this question, it might help you.

+2

Uhm, C++ - Streams * werden standardmäßig gepuffert, entweder direkt oder über 'stdio' (gepuffert); Außerdem werden selbst die Puffer des Betriebssystems gelesen, so dass es unwahrscheinlich ist, dass er die Festplatte kontinuierlich trifft. –

+0

hımm, ich wusste das nicht. ist es möglich, dass die Puffergröße klein ist? Wenn dies der Fall ist, kann die manuelle Änderung der Puffergröße hilfreich sein. – Dante