Große Datei möglichst schnell in kleinere Dateien aufteilen.



  • kannst du eine beispieldatei verfügbar machen (am besten ein kleines programm, das echt aussehende daten und davon 800M schreibt)?



  • ich fürchte, es ist optimal, für jede id eine std::queue zu nehmen und nach je 1000 (einstellbar) jelesenen zeilen die längste queue an ihre ausgabedatei dranzuhängen (mit append schreiben).

    tricks mit viel filemapping und co bringen nur faktor 2, würde ich schätzen.



  • volkard schrieb:

    ich fürchte, es ist optimal, für jede id eine std::queue zu nehmen und nach je 1000 (einstellbar) jelesenen zeilen die längste queue an ihre ausgabedatei dranzuhängen (mit append schreiben).

    tricks mit viel filemapping und co bringen nur faktor 2, würde ich schätzen.

    Hallo Volkard!

    Leider darf ich nichts rausgeben 😞

    Deine Lösung gefällt mir aber recht gut, da werde ich auch noch versuchen anzusetzen.



  • aviator schrieb:

    Leider darf ich nichts rausgeben 😞

    Du sollst ja auch nonsense daten erstellen, nur eben welche, die die struktur der echten daten haben.

    sowas verwendet man gerne zum testen 🙂



  • vielleicht pro id nen puffer von 128k, damit man kein malloc/new mehr braucht. ist der puffer voll, wird weggeschrieben. keine verkette liste mehr.



  • Würde es so auch Sinn machen?

    Du speicherst alle ostreams in einem std array.
    So musst du die nicht mehr in der for-Schleife schließen, sondern hat sie alle offen in einem Array.

    Oder du schreibst alle Zeilen in einen vector und sortierst nach der ID.
    Dann gehts du eben durch und schreibst in die Datei, die zur ID gehört.
    Kommt eine neue ID, dann machste einfach eine neue Datei auf.

    struct data_t {
      size_t id;
      string zeile;
    
      bool operator <(const data_t& rhs) {
        return id < rhs.id;
      }
    };
    vector<data_t> box;
    data_t temp;
    stringstream s;
    for(string line; getline(file, line);)
    {
      s = line.substr(0,4);
      temp.id = s; // Ich bin mir nicht sicher, ob das so geht!
      temp.zeile = line;
      box.push_back(temp);
    }
    
    sort(box.begin(), box.end();
    
    size_t oldId = 0;
    size_t newId = 0;
    ofstream out;
    for(vector<data_t>::const_iterator it = box.begin(); it != box.end(); ++it) {
      newId = it->id;
      if(newId != oldId)
      {
        if(out.is_open()) out.close();
        s = it->id;
        s += ".txt";
        out.open(s.str(), ios::app);
      }
      out << it->zeile;
      oldId = newId;
    }
    if(out.is_open()) out.close();
    
    // Ich bin mir nicht sicher, ob das alles so stimmt,
    // wie ich es geschrieben habe
    // Da hoffe ich einfach auf euere Kritik!
    
    // restliche Aufräumarbeiten
    


  • Sorry das ich mich nicht mehr gemeldet habe, aber das Problem hat mich tierisch aufgeregt. Nach jetzt stundenlangen rumprobieren bin ich zu der Erkenntnis gekommen das Volkard recht hatte, seine Lösung ist wirklich am schnellsten.



  • Wenn du das programmiert hast, würde mich der Ausschnitt brennend interessieren.



  • wie schnell ist es denn geworden?



  • hehejo schrieb:

    Würde es so auch Sinn machen?

    Nur wenn die Daten in den RAM passen, sonst nicht.

    und 800MB ist da schon etwas viel...


Anmelden zum Antworten