Frage

Ich habe einige Datendateien, die als Tag = value geschrieben wurden, wobei Tag Zeichenfolge und Wert ist, der numerisch, Zeichenfolge, Array usw. ist. Ich verwende dieses Format, da lesbar ist und einfach bearbeitet werden kann. Jetzt hat jede Klasse, die mit diesem Format instanziiert wird, eine Lastmethode und liest die Tags, die sie benötigt, und verwendet die in diesen Tags gefundenen Werte. Ich möchte die Daten binär machen, um die Ladegeschwindigkeit zu erhöhen. Eine Möglichkeit wäre, in jeder Klasse, die die alten Daten liest, eine tabinäre Methode (der Name spielt keine Rolle) zu haben, die die alten Daten liest und in eine Datei schreiben, und die neue Datei wird verwendet, um das Objekt zu instanziieren. Dies kann offline, nur einmal/Anwendung. Haben Sie dafür andere Vorschläge? Ich benutze dafür C ++.

Bearbeiten: Ich denke, der teuerste Teil ist es jetzt, die Datei zu analysieren, wenn ich sie zum ersten Mal gelesen habe, und danach das von mir benötigte Tag zu durchsuchen, um die Datei nicht von der Festplatte zu lesen. Ich kann ein benutzerdefiniertes Dateisystem verwenden, um mehrere kleine Dateien in einer großen Datei zu haben.

War es hilfreich?

Lösung

Ich habe eine Serialisierungsbasisklasse dafür, mit Funktionen mit einem kleinen Header, in dem die Versionshandhabung eingebettet werden kann. Ich denke, es ist ein gutes System für einfachere Daten, die lokal gespeichert werden müssen, und in den meisten Fällen ist "nur lesen".

Etwas wie das:

class SeralizeMe
{
public:

 virtual bool To(Archive &file)=0;
 virtual bool From(Archive &file)=0;

 virtual bool NeedsSave(void)=0;

};

Verwenden Sie dieses System jedoch nicht, wenn Sie:

  • Muss das Format häufig ändern.
  • Muss auswählen, welche Daten geladen werden sollen und was gespeichert werden soll.
  • Verwenden Sie große Dateien, die während des Speicherns für Stromausfälle von Partikeln empfindlich sind.

Wenn eine der oben genannten Anwendungen eine Datenbank verwenden, ist Firebirdsql eingebettet ein geeigneter Anwärter.

Andere Tipps

Ich habe es noch nicht benutzt, aber ich bin sicher, ich bin sicher Das Serialisierungsmodul von Boost ist ein guter Ausgangspunkt.

Wenn Sie eine Datei verwenden, verbessert die Verwendung von Binärdaten Ihre Leistungen wahrscheinlich nicht wesentlich, es sei denn, Sie haben einen sehr großen Datenbeteils zum Speichern in der Datei (Bilder, Videos ...).

Aber trotzdem können Sie einen binären Serialisierungsalgorithmus verwenden, wie der von Schub.

Ein anderer ist Protobuf von Google. Nicht die schnellsten, aber es kann sich entwickelnde Datentypen unterstützen und ist über das Netzwerk sehr effizient und unterstützt andere Sprachen.

Verknüpfung hier.

Wenn Sie die Leistung verbessern möchten, müssen Sie Felder mit fester Länge verwenden. Das Parsen oder die Ladefelder variabler Länge liefern keinen signifikanten Leistungsanstieg. Das Lesen nach Textzeile beinhaltet das Scannen nach dem Ende des Linien -Tokens. Scannen verschwendet Zeit.

Profilieren Sie vor Verwendung einer der folgenden Vorschläge Ihren Code, um eine Basiszeit oder -zahl für die Leistung festzulegen. Tun Sie dies nach jedem Vorschlag, da Sie es ermöglichen, das zu berechnen Performance Delta jeder Optimierung. Meine Vorhersage ist, dass das Delta bei jeder Optimierung kleiner wird.

Ich schlage vor, zuerst die Datei in festgelegte Längendatensätze zu konvertieren und weiterhin mit Text. Padfelder mit Bedarf mit Räumen. Wenn Sie die Größe eines Datensatzes kennen, können Sie das Lesen in den Speicher blockieren und den Speicher als Array behandeln. Dies sollte eine signifikante Verbesserung bieten.

Zu diesem Zeitpunkt sind Ihre Engpässe immer noch eine Datei -E/A -Geschwindigkeit, bei der Sie nicht wirklich signifikante Verbesserungen vornehmen können (da die Datei -E/A vom Betriebssystem gesteuert wird) und Text scanning/konvertieren. Einige weitere Optimierungen sind: Text in Zahlen konvertieren und schließlich in binär umwandeln. Voraus, die Datendatei auf jeden Preis in menschlich lesbarem Formular zu halten.

Bevor Sie die Datendatei weniger lesbar machen, teilen Sie Ihre Anwendung in Threads auf. Ein Faden behandelt die GUI, ein anderes die Eingabe und ein anderes für die Verarbeitung. Die Idee ist der Prozessor stets Führen Sie etwas von Ihrem Code aus, anstatt zu warten. In modernen Plattformen kann die Datei -E/A durchgeführt werden, während die CPU Ihren Code verarbeitet.

Wenn Sie sich nicht für die Portabilität interessieren, prüfen Sie, ob Ihre Plattform DMA -Funktionen verfügt (eine DMA- oder Direktspeicherzugriffskomponente ermöglicht Datenübertragungen, ohne den Prozessor zu verwenden oder die Verwendung des Prozessors zu minimieren). Etwas, auf das man achten muss, ist, dass viele Plattformen den Adress- und Datenbus zwischen Prozessor und DMA teilen. Somit wird die eine Komponente blockiert oder suspendiert, während die andere die Adresse und die Datenbusse verwendet. Es kann also helfen oder nicht. Hängt davon ab, wie die Plattform verkabelt wird.

Konvertieren Sie das Schlüsselfeld, um Nummern zu verwenden, auch bekannt als AKA Token. Da die Token numerisch sind, können sie als Indizes in Sprungtabellen (auch Anweisungen) oder nur Indizes in Arrays verwendet werden.

Konvertieren Sie die Datei als letztes Mittel in Binärdatei. Die binäre Version sollte zwei Felder haben: Schlüssel als Token und Wert. Ziehen Sie die Daten in großen Stücken in den Speicher ein.

Zusammenfassung

  1. Zieh große Datenblöcke in den Speicher.
  2. Profil, bevor Änderungen vorgenommen werden, um eine Basisleistungsmessung festzulegen.
  3. Optimieren Sie einen Schritt nacheinander und profilieren Sie nach jeder Optimierung.
  4. Vorziehen Sie die Datendatei in menschlich lesbarem Formular.
  5. Minimieren Sie Änderungen an der Datendatei.
  6. Konvertieren Sie die Datei, um Felder mit fester Länge zu verwenden.
  7. Versuchen Sie, Threads oder Multitasking zu verwenden, damit die Anwendung nicht wartet.
  8. Text in numerische Token konvertieren (reduziert die menschliche Lesbarkeit)
  9. Konvertieren Sie Daten als letztes Ausweg in Binary (sehr schwierig für Menschen zu lesen und zu debuggen).

Ich habe zwei Ideen für Sie:

1) Wenn die Liste der Tags konstant und im Voraus bekannt ist, können Sie jeden in ein Byte (oder ein Wort) umwandeln, gefolgt von der Länge des Wertes (in Bytes), gefolgt von der rohen C-String des Wertes des Werts des Wertes Nutzlast.

Zum Beispiel angesichts der folgenden:

Tag1 = "hello World!" // 12 bytes in length (achieved by "strlen(value) * sizeof(char)" )
Tag2 = "hello canada!"  // 13 bytes in length 

Sie könnten dies in den Byte -Stream verwandeln:

0x0001 0x000B // followed by 12 bytes representing the 'value' // 0x0002 0x000C // followed by 13 bytes representing 'value2'

Ihr Programm müsste nur wissen, dass das Wort Header "0x0001" Tag1 darstellt und der Header "0x0002" Tag2 darstellt.

Sie könnten die Tagennamen noch weiter abstrahieren, wenn Sie sie im Voraus nicht kennen, indem Sie einer ähnlichen Wertstruktur und einer ähnlichen Wertstruktur folgen.

2) Vielleicht ist das langsame Stück nur Ihre Implementierung des Textesanalysens? Erwägen Sie, eine dedizierte Open -Source -Bibliothek für das zu verwenden, was Sie versuchen. Beispiel: "Boost :: Property_Tree"

Die Eigenschaftsbaum ist speziell für das Speichern und Abrufen von Schlüsselwertpaaren ausgestattet (für die Datei für Konfigurationseinstellungen ausgelegt). Aber ich denke, es würde abhängen, wie viele solcher Paare Sie versuchen, um wirtschaftlich zu speichern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top