Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

07.12.2012, 23:25

XML Datenspeicherung sinnvoll?

Hallo liebes Forum!

Ich bin bei einem Projekt auf einen Punkt gestoßen, bei dem ich nicht mehr ganz weiß ob meine Überlegungen schlüssig und auch wirklich sinnvoll sind.

Konkret geht es um folgendes: Ich brauche für ein Programm, geschrieben in C++, eine Art Datenbank, ein Wörterbuch. Das Programm soll sich aus den Dokumenten Informationen holen. Nun stehe ich vor der Frage, wie ich diese Datenbanken gestalten werde, ob mit XML oder einfachem Blank-Text.

Meine Gedanken einmal kurz zusammengefasst:

XML ist wunderbar erweiterbar und bietet sehr viele Möglichkeiten. Beispielsweise im Webdevelopment, wenn man etwa mit JavaScript Informationen aus derartigen Dokumenten ausliest um damit dann Tabellen mit Werten zu füllen.
Man braucht jedoch einiges an Zeichen um die Tags wirklich auszuformulieren, somit ist der Speicherverbrauch erhöht und das interpretierende Programm muss dann die einzelnen Tagnamen lesen, was wiederum Rechenzeit in anspruch nimmt.

Blank-Text ist einfach zu lesen und wenn ich gewisse Punkte vordefiniere, dann sollte dieser Vorgang auch wesentlich einfacher ablaufen und platzsparender als auch ressourcenfreundlicher sein. Ich hab hier einfach einmal kurz wie ich mir vorstelle, dass das Ganze dann aussieht:

wort1.0übersetzung

Ich habe mir das so gedacht: Das erste Wort wird solange gelesen, bis die Zahl erreicht ist. Von diesem Wort gehe ich aus. Die Zahl gibt Informationen über Dinge wie etwa Wortart, also Nomen, Verb, etc. Das Wort danach ist dann die eigentliche Übersetzung.

Ich will alles so sparsam wie möglich machen. Wie bereits gesagt, XML bietet viele Vorteile, ich kann mir etwa vorstellen, sollte ich einmal gewisse Informationen erweitern wollen, so ginge das hiermit wesentlich besser. Aber durch all die Strukturen die entstehen verbrauche ich doch einiges an Platz, selbst wenn das heutzutage weniger ein Problem ist, ich übe noch, deshalb gehts mir unter anderem auch darum den Unterschied zwischen Optimierung und Unsinn kennenzulernen.

Es würde mich freuen, wenn ihr mir eure Erfahrungen und Meinungen mitteilt. Ich finde es immer spannend wie andere zu solchen Dingen stehen :) .

Danke im Voraus für eure Antworten!

Lg
Hans_Peter

PS: Ich bin auch nur ein Mensch, sollte ich etwas vergessen haben, ich kann es gerne nachtragen :D .

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

07.12.2012, 23:40

Verwende XML und komprimiere die Dateien einfach. ;)

Alternativ zu XML kannst du SQLite verwenden. Eine SQL Datenbank empfinde ich persönlich viel angenehmer als XML-Dateien.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

3

07.12.2012, 23:47

XML ist das wohl bescheuertste Serialisierungs-Format, das mir je untergekommen ist, und das mit dem absurd höchsten Overhead an Nutzlos-Daten. Dennoch halte ich die Speicherung von Daten in einem lesbaren Format sinnvoll, solange die Lesbarkeit kein Problem darstellt, oder die Größe der Datei. Ich empfehle dir aus boost den property_tree und den zugehörigen Info-Parser. Info ist ein Serialisierungs-Format, das für boost::property_tree entwickelt wurde, und YAML sehr ähnlich ist. Da wäre dann auch schon das nächste Format: YAML. Wundervolles Zeugs.
Wenn dir die Lesbarkeit nicht wichtig ist, böte sich eine kompakte SQL-Datenbank an, oder - was ich präferieren würde - boost::serialization. Wenn ich mich nicht irre, sind beides Header-only-Libs. Ich verwende sie auch für meine Projekte.

Edit:
Mir ist etwas weit interessantereres eingefallen, was aber dafür womöglich ein Overkill wäre und sich auch mit Bastelei in YAML und Info realisieren ließe. Du könntest LuaJIT einbauen und die Datenbank als Lua-Code auslegen. Sähe z.B. so aus:

Quellcode

1
2
3
4
5
vocab{
  trans{'a','b'},
  trans{'asdf','uiae'},
  trans{'elektron','Bernstein'},
}

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

4

07.12.2012, 23:50

Du willst ja vermutlich später Wörter suchen und Übersetzen und so. Dafür brauchst du irgendwann auf jedenfall eine Beschleunigungsstruktur, etwa einen Suchbaum, da du sonst alle Daten durchlaufen musst, was zu langsam ist.
Eine richtige Datenbank wie SQL bietet dir genau solche Suchfunktionen und außerdem noch den Vorteil, dass nicht alle Daten im RAM sein müssen (bei mehreren GB geht das ja auch gar nicht).

Wenn du es selber machen willst, musst du halt irgendwie in der Datei schon in die Nähe des richtigen Wortes springen ohne die ganze Datei vorher gelesen zu haben. Mit XML wird das sehr schwierig.
Die Frage ist, wie viele Daten wirst du am Ende haben? Wirklich im GB Bereich? Oder doch nur ein paar MB? Im letzteren Fall kannst du auch alle Daten in eine XML Datei schreiben, beim Programmstart in den RAM laden und da weiter arbeiten. So schlimm ist der Overhead dann doch nicht.
Lieber dumm fragen, als dumm bleiben!

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

5

07.12.2012, 23:57

Beschleunigen könnte man es im Zweifelsfall auch mit std::unordered_map<>. Macht schon ganz schön was her. Natürlich bedeutet das allerdings, dass die gesamten Daten im RAM landen würden, sofern man sie nicht in mehrere Teil-Dateien aufspaltet oder sich etwas beim Laden einfallen ließe. SQL hat da also den Vorteil, dass man am wenigsten selbst basteln müsste.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

6

08.12.2012, 12:21

Ggf ist auch json eine einfache Option, weil das ist an die dict von python angelehnt und perfekt fürs speichern, allerdings muss man halt immer erst alles komplett durchparsen (genauso wie bei XML). Dafür ist es recht schnell und leicht. http://www.json.org/
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

7

08.12.2012, 13:12

Das .ini-Format ist ziemlich deprecated und nicht sehr übersichtlich für hierarchische Datenstrukturen. JSON ist im Übrigen witziger Weise gültiges YAML. Ich weiß nicht, wie es JSON geht, aber YAML bietet eine Syntax, die nachstehenden Daten an Fabrik-Funktionen weiter zu reichen. Also eine Syntax, die die nachstehenden Daten als serialisierte Member einer Instanz einer Klasse signalisiert. Diese Fabrik-Funktionen muss man dann bloß noch einbauen.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

08.12.2012, 17:41

Geht es hier um einfache Übersetzungssoftware? Wenn ja, dann macht eine Art ini-File sehr wohl Sinn. Schreib deine Daten einfach in eine Textdatei. Zeile für Zeile. Dabei sollten die Daten lexikografisch geordnet sein. Also genau so wie in einem Wörterbuch. Die Daten ließt dein Programm nun ein und generiert eine geeignete Datenstruktur. Nun jetzt ist die Frage, welche Datenstruktur dafür geeignet ist. Am einfachsten wäre natürlich eine Art Array. Das würde jedoch in schlechten Laufzeiten resultieren. Eine Wortsuche im Array hätte eine Laufzeit von n. Das geht natürlich um einiges schneller. Ein Binärer Suchbaum zum Beispiel ist schnell implementiert und du kannst mit log(n) Elemente finden. Das wäre recht einfache Optimierung, aber dafür auch einfache Implementierung. Man könnte nun weiter überlegen, wobei das den Implementierungsaufwand aufblähen würde. Voraussetzung ist hierfür, dass alle Daten aktuell im Speicher gehalten werden dürfen. Also auch hier gilt, möglichst keine GB an Daten. Ansonsten würde ich auch ganz klar zu einer Datenbank raten. Die arbeiten mit hochoptimierten Algorithmen und Baumstrukturen im Hintergrund. Das möchtest du gar nicht selbst schreiben;)

edit: Wenn du den Schlüssel des Paares schon kennst, also zum Beispiel ein Wörterbuch Deutsch-Englisch programmierst und der deutsche Begriff schon bekannt ist, zum Beispiel "Auto", dann kannst du die Daten auch einfach in einer Map speichern. "Auto" wären dann der Schlüssel und "Car" der zugehörige Value. Im Value kannst du dann deine zugehörigen Zahlen und was weiß ich welche Informationen noch zusätzlich mit abspeichern. Aber auch hier gilt, keine GB Daten;)
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

9

09.12.2012, 12:49

Hallo und erstmal ein großes Danke meinerseits für eure Antworten!

Ich denke das Beste wird sein, wenn ich einfach mal auf alle eingehe.

XML ist das wohl bescheuertste Serialisierungs-Format, das mir je untergekommen ist, und das mit dem absurd höchsten Overhead an Nutzlos-Daten.

Ja, genau das dachte ich mir anfangs auch, welshalb ich hier gefragt habe. Informationen die ich schlichtweg nicht verwenden kann, noch dazu das parsen der einzelnen Tags sah für mich einfach als zu großer Arbeitsaufwand aus, der letzten Endes nur hinderlich ist.
Ich muss aber sagen, ich hab selbst noch ein bisschen herumprobiert und meinen Langenscheidt ausgepackt und dann einfach einmal Worte ins "Wöterbuch" geschrieben. Dabei sind immer wieder neue Dinge hinzugekommen, also Informationen die beachtet werden mussten, etwa bei dem Wort "abdecken":

abdecken: to cover; Dach to take off; Haus to take the roof off; Tisch to clear

Ich hab das ganze auf zwei Weisen getestet, einmal mit einer normalen Textdatei, wobei ich ein bestimmtes Muster verwendet habe, das möglichst sparsam sein sollte und durch einen Algorithmus "decodiert" werden sollte. Bei der zweiten Datei habe ich eine XML-Struktur verwendet, die natürlich viel größer war als die erste Datei, mehr als doppelt so viel. Allerdings hatte ich hier den Vorteil von XML auf meiner Seite: Der Algorithmus kann bestimmte Tags bereits lesen, die die er nicht kennt lässt er weg und somit kann man später immer wieder Informationen ergänzen. Der Grund warum diese Art der Datenspeicherung überhaupt für mich in Frage kommt.

Wenn du es selber machen willst, musst du halt irgendwie in der Datei schon in die Nähe des richtigen Wortes springen ohne die ganze Datei vorher gelesen zu haben. Mit XML wird das sehr schwierig.

Das ist eine Sache die ich mir auch schon überlegt habe. Ich hatte ganz primitive Lösungsansätze: Wieso sollte ich alle Wörter in eine Datei schreiben, ich mach Dokumente für jeden einzelnen bekannten Buchstaben, also etwa so:

a.dictionary
b.dictionary
...

somit sollte ich es mir prinzipiell ersparen bei dem Wort "brechen" auch noch alle Worte mit "a" beginnend einzulesen, da ich einfach den Anfangsbuchstaben verwende um die entsprechende Datei zu suchen.
Bin ich dann in der Datei so dachte ich an eine Art Verzeichnis, welches mir im Fall des Wortes "brechen" sagt, so die Worte mit "br" beginnend anfangen, in XML etwa so:

<index line="123">b</index>
<index line="456">c</index>
...

Ich springe dann in die entsprechende Zeile und setzte dort meine Suche fort. Damit die Daten nicht unnötig groß werden und es nur um die Erweiterbarkeit und nicht um die optimale Lesbarkeit geht, dachte ich könnte man oberes auch so gestalten:

<i l="123>b</i>
...

für einfache Datenspeicherungen so wie in der win.ini

Ich muss gestehen, mit ".ini"-Dateien kenne ich mich nicht wirklich aus...allerdings dachte ich bisher, dass sie eher veraltet seien, wobei ich wie gesagt wenig Ahnung davon habe, also tut es mir leid wenn ich mich irre.

Geht es hier um einfache Übersetzungssoftware? Wenn ja, dann macht eine Art ini-File sehr wohl Sinn. Schreib deine Daten einfach in eine Textdatei. Zeile für Zeile.

Das war meine ursprüngliche Idee, allerdings tat sich mir dann ein Problem bei dieser Stelle auf:

Die Daten ließt dein Programm nun ein und generiert eine geeignete Datenstruktur.

weil ich wie gesagt sehr schnell gemerkt habe, dass immer wieder neue Informationen hinzukommen und das Programm dementsprechend modifiziert werden muss, damit es damit umgehen kann. So etwas ist mir mit der XML-Version nicht passiert.

Ein Binärer Suchbaum zum Beispiel ist schnell implementiert und du kannst mit log(n) Elemente finden.

Das klingt sehr interessant, könntest du mir das bitte noch einmal genau erklären?

Voraussetzung ist hierfür, dass alle Daten aktuell im Speicher gehalten werden dürfen. Also auch hier gilt, möglichst keine GB an Daten.

Ich wollte mit den oben beschriebenen Ansätzen dafür sorgen, dass ich möglichst wenig meines kompletten Wörterbuches einlesen muss. Es ist doch so, dass wenn ich eine Datei bzw. einen Stream öffne, dass ich dadurch noch keine Daten im Speicher halte, oder irre ich mich? Wenn nicht, dann würde ich ohnehin immer nur Zeile für Zeile einlesen, wobei nicht passende Werte einfach wieder aus dem Speicher genommen werden.

Das alles sind allerdings nur grobe Vorstellungen. Ach und

Geht es hier um einfache Übersetzungssoftware?

Naja, etwas von mir produziertest verdient den Namen "Software" eigentlich nicht ^^ . Es geht um ein Übungsprojekt von mir, bei dem ich mich mit eben Datenspeicherung und anderem beschäftigen wollte, unter anderem auch das übersetzten von ganzen Satzgebilden, wobei diese sich so wie ich mich kenne nur auf einfache 3-Wort-Sätze beschränken werden.

Jetzt würde mich interessieren, wenn ihr beispielsweise Spiele schreibt, wie speichert ihr eure Daten?

Ich bedanke mich jetzt schon einmal für eure Antworten!

Lg
Hans_Peter

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

10

09.12.2012, 14:20

Zitat

Das klingt sehr interessant, könntest du mir das bitte noch einmal genau erklären?
Wenn du deine Wörter in einer std::unordered_map speicherst, hast du die meiste Zeit eine Mächtigkeit von O(1) (In seltenen Pechfällen O(m), wobei das m hier nicht die Zahl aller Elemente ist). Das hängt natürlich auch vom verwendeten Hash-Algorithmus ab, aber der Standard-Algo macht schon gut was her. Damit haste einen weit schnelleren Zugriff als mit einem binären Suchbaum und zahlreichen Elementen.

Was die Erweiterbarkeit betrifft, so sollten dir auch YAML und Info nicht im Weg stehen. Lohnt sich zumindest, sich die Teile mal anzuschauen.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Werbeanzeige