Geschwindigkeitsprobelm beim speichern daten in datei



  • Hast du/deine Firma einen Profiler? Damit lassen sich Performanceengpässe gut aufspüren, vielleicht hakt´s ja an einer ganz anderen Stelle? Zur Not kannst du dir mit QueryPerformanceCounter und QueryPerformanceFrequency selbst eine hochpräzise Uhr bauen, mit der du die Ausführungszeit der Einlesefunktion messen kannst. Ich glaube nicht, dass das Einsparen einiger String Kopien einen spürbaren Geschwindigkeitsvorteil bringt.



  • DocShoe schrieb:

    Hast du/deine Firma einen Profiler? Damit lassen sich Performanceengpässe gut aufspüren, vielleicht hakt´s ja an einer ganz anderen Stelle?

    Auch meine Empfehlung. Am besten wäre natürlich ein Kaliber wie AQtime, aber für eine Kleinigkeit tut es auch Thomas Neumanns SampleProfiler (Standalone-Build hier).



  • So, ich denke ich weiß woran es liegt, bzw. leider nicht genau. 😞

    Aber da habt ihr bestimmt Erfahrung und könnt mir helfen.

    Ich habe das Programm mit den Listen auf einen Laufwerk in unseren Hausnetz gespeichert, damit auch jeder darauf zugreifen kann.

    Jedoch wenn ich das Programm auf C: lokal auf den Rechner zb. desktop kopiere und von dort aus starte funktioniert es so wie es soll, zeitnah per mausklick wird es auch in die liste eingetragen und in die datei gespeichert... juhuu!

    Aber.. ich muss ja die listen auf den Hausnetz legen, damit auch jeder darauf zugreifen kann.

    Woran kann das jetzt genau liegen? bzw. was kann ich dagegen tun?

    Danke, mfg

    PS: Habe mir das mit der Zeitmessung angeschaut und werde dies auch nutzen um die Funktionen zu optimieren 😃 thx



  • Mäxchen schrieb:

    Jedoch wenn ich das Programm auf C: lokal auf den Rechner zb. desktop kopiere und von dort aus starte funktioniert es so wie es soll, zeitnah per mausklick wird es auch in die liste eingetragen und in die datei gespeichert... juhuu!

    Liegen bei dieser Gegenprobe auch die zu bearbeitenden Listen auf dem lokalen Rechner, oder sind sie weiterhin auf dem Server und werden über das Netz geladen bzw. gespeichert?



  • Also sobald ich die Listen lokal abspeicher funktioniert das speichern in einer klasse geschwindigkeit, aber sobald die Dateien dann im Netzwerk liegen und dort gespeichert werden dauert es ewig lang...

    Wo das Programm selbst gespeichert ist, ist egal...

    Wie würdet ihr vorgehn?

    Danke. Gruß
    Mäxchen



  • Wie lange dauert denn das einfache kopieren der Datei aufs Netzwerk?



  • ofstream out("datei.txt);
    out<<inhalt;
    

    ich speicher so im groben ab, und das dauert 3,3sec.
    Wenn ich lokal speichere, dauert es gerade mal 0,02sec



  • Der Ansatz selbst ist schon zum Scheitern verurteilt. Wenn mehrere Benutzer (darum liegt die Datei wohl auf einem Netzlaufwerk) schreibend auf eine Datei zugreifen ist es nur eine Frage der Zeit, bis entweder die Datei kaputt ist oder Konflikte auftreten. Es mag zwar selten auftreten, aber es wird irgendwann auftreten. Nach Murphy treten solche Fehler immer am unglücklichsten Zeitpunkt auf.

    Was ist passiert in folgendem Szenario:

    - Benutzer A lädt die Datei lokal in den Speicher seines Computers
    - Benutzer B lädt die Datei lokal in den Speicher seines Computers
    - Benutzer A ändert Zeilen 5 und 6 und schreibt dann die Datei neu
    - Benutzer B ändert Zeile 3 und schreibt die Datei dann neu

    => Änderungen des Benutzers A gehen verloren, weil Benutzer B von diesen Änderungen nichts mitbekommen hat
    => Versionskonflikt

    Du brauchst auf jeden Fall irgendeine Art von Zugriffssynchronisierung, im einfachsten Fall vielleicht so etwas wie alleinigen Schreibzugriff auf die Datei zusammen mit der Kennzeichnung neuer Daten. Für das obige Beispiel könnte das folgendermassen aussehen:

    1. exklusiver Zugriff auf die Datei für den Schreibmodus
    2. Statusfeld für jeden Eintrag (dirty/clean). Damit erkennst du, welche Einträge geändert worden sind und welche ihren alten Inhalt behalten. Beim Schreiben der Daten ersetzt du dann lediglich die Einträge, die mit dirty markiert sind, alle anderen werden aus der Datei übernommen. Das löst die Versionskonflikte, wenn mehrere Benutzer gleichzeitig Änderungen an der Datei vorgenommen haben und so nur die geänderten Daten geschrieben werden, anstatt die komplette Datei zu überschreiben.
      Am besten automatisierst du das Lesen/Ändern/Schreiben durch eine Test Unit, die in unregelmässigen Abständen die Datei liest, ändert und zurückschreibt. Dann startest du mehrere Instanzen, lässt das mal über Nacht/Wochenende laufen und guckst dir das Ergebnis an.


  • Ich habe mir das so gedacht, ich lege eine Datei an, wo mit 1 und 0 beschrieben ist, ob irgendeine Liste geändert wurde und wenn ja, welche. Während das Programm dann läuft, soll abgefragt werden und dann eventuell die neue Liste einlesen.

    Quasi wird das dann abgefragt, bei re aktivieren vom programm, oder kurz bevor man speichern will.

    So ähnlich habe ich mir das vorgestellt.
    Wenn mehrere offen sind wird gespeichert wieviel quasi online sind.
    zB: es sind 4 online und einer hat eine Datei geändert, dann kommt der code 13, quasi steht die 1 dann für Datei verändert, und die 3 für die anzhal die noch einen refresh machen müssen. Wenn dann einer neu einliest ändert er den code auf 12, zum schlus dann 00, und somit ist jedes Programm auf den aktuellen Stand...

    Aber wenn ich mir das recht überlege, wie soll ich das handhaben wenn 2 gleichzeitig etwas ändern...oh weh...

    Wie realisier ich das wohl am einfachsten...

    Das mit den unregelmäßigen einlesen und ändern, mit dirty und clear ist eine gute Lösung, aber doch sehr aufwändig.!?

    Aber ich würde noch immer ganz gern wissen warum das speichern auf dem netzlaufwerk sooo extrem lange dauert!??

    Danke. Gruß
    Mäxchen



  • Hallo

    Du könntest dir nun ein Programm schreiben, das aktiv auf dem Server (dort wo jetzt deine Datei liegt) den Zugriff auf die Daten für die Clients verwaltet. Oder einfach eine vorhandene Datenbanklösung wie MySQL, Postgre oder Firebird verwenden, denn genau dazu sind Datenbanken da.

    bis bald
    akari



  • Ja, mit Hilfe einer Datenbank wäre das ganze wohl um einiges einfacher..

    Aber leider bin ich nicht von der IT und die werden mir auch keine Berechtigung geben..

    also löse ich das mit einer "status.dat". 🙂



  • Da beisst sich doch die Katze selbst in den Schwanz. Für die Status.dat existieren doch die gleichen Probleme wie für die eigentlichen Daten.

    Dieser Ansatz für das Schreiben sollte doch funktionieren:

    1. Datei im Exklusiv-Schreibmodus öffnen
    2. falls nicht erfolgreich, kurze Pause, zurück zu 1), ggf. abbrechen
    3. Dateiinhalt einlesen
    4. alle Zeilen, die im Speicher als dirty markiert sind, in die frisch eingelesenen Daten übertragen
    5. geänderten Daten schreiben und Datei schliessen


  • Nachtrag:
    Es gibt auch noch so Sachen wie embedded, self contained Datenbanksysteme (z.B. SQLite oder HamsterDB), die keine Installation eines DBMS voraussetzen sondern als DLL oder statische Bibliothek daherkommen und gegen die Anwendung gelinkt werden. Allerdings kenne ich keine, die prozessübergreifende Synchronisation unterstützt.



  • Warum es so langsam ist: die Datei wird häppchenweise angefordert und nach jeder Anforderung muss auf die Antwort gewartet werden.
    Also erst die Datei komplett einlesen, und erst dann verarbeiten.
    Beim Schreiben genauso, erst alle Daten vorbereiten und dann alle aufs Mal schreiben (bzw. in Blöcken bei sehr großen Dateien).



  • Ok, Idee:

    Da ja beim Schreiben die 3 sec zustande kommen, würde ich dann die komplette Datei lokal in irgendein temp verzeichnis speichern und anschließen mit einer c++ funktion komplett ins netz kopiere. Ist das ein möglicher Lösungsweg?

    Mit welcher Funktion kann ich die Datei dann kopieren? bzw. Verschieben?

    @DocShoe
    Ich weiß genau was du meinst. aber da
    das Programm höchstens von 5 Benutzer gestartet wird und diese höchstens jeder 10 Einträge an einem Tag eintragen werden ist das nicht sooo schlimm.
    Das kleine Risiko geh ich ein.

    zudem wird ja, bevor ein Schreibvorgang beginnt ein Status auf 1(in status.dat) gesetzt, der danach wieder auf 0 gesetzt wird. Somit weiß ein anderes Programm das es nicht schreiben kann bzw. die liste dann nochmal neu einlesen muss und dann die änderung vom 2. Programm speichern muss.

    Danke. Gruß
    Mäxchen


Anmelden zum Antworten