Autor |
Beitrag |
Chatfix
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Fr 21.10.05 12:59
Hallo, ich wollte fragen wie ich ein Festes Array vom Typ eines Records in einem XML abspeichere, bzw. ob das überhaupt geht.
Der Record besteht aus mehreren ShortStrings, Integer, Boolischen, weiteren ShortString Arrays und Date-Werten.
Zur Zeit speichere ich dies über einen Rekord über einen Stream jedoch wird bei 10000 einträgen die datei schon über 50 mb groß 
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 21.10.05 13:27
Hmm, sooo klein wird aber eine XML-Datei auch nicht, es wird ja lediglich der Overhead durch die Leerzeichen am Ende der Strings (sofern diese eine feste Länge haben, wovon ich ausgehe) vermieden, dafür kommt aber der XML-Code hinzu.
Klar, das ist kleiner, aber nicht am kleinsten.
Wenn ich sowas mache, dann speichere ich den Record entweder mit einer eigenen (dann aber natürlich knallhart optimierten) Methode, wobei ich keine Strings mit fester Länge benutze sondern die Länge jeweils mitspeichere, oder ich komprimiere einfach das Ganze.
Beides hat Vor- und Nachteile. Wenn der Record Eintrag für Eintrag gespeichert wird, könnte es bei sehr vielen Einträgen zu lange dauern.
Beim Komprimieren dauert das Komprimieren nach dem Speichern nochmal kurz.
Beim LZRW1/KH Algorithmus von Kurt Haenen geht das Komprimieren von 50 MB aber relativ schnell (auf nem AMD 3800er schätzungsweise 3-4 Sekunden nach meiner Messung, die ich eben gemacht habe...)!
Dieser Algorithmus ist nicht sonderlich gut was die Komprimierungsrate anbelangt, aber bei Records mit Strings mit fester Länge ist er relativ gut, weil viele gleiche Zeichen da sind.
Mein Vorschlag: Versuch mal erstmal den Stream zu komprimieren, vielleicht ist das ja schon klein genug.
Was XML angeht: Was suchst du eigentlich? Eine Komponente bzw. Source, der da was automatisiert tut oder Vorschläge zur Realisierung?
Allerdings bezweifle ich eigentlich, dass XML schneller geht als den Record selbst Eintrag für Eintrag zu speichern und so die Größe zu verkleinern...
Am besten wäre vielleicht, wenn du mal den Record angibst, und vor allem, inwieweit Strings drin sind, die oft nur zu einem kleineren Teil Daten enthalten.
Dann könnte ich mal selbst testen, was wie schnell ist, denn ohne den Record zu kennen, kann ich ja keine wirklich passenden Geschwindigkeitstests durchführen.
Hinweis: Ich bin erst Montag wieder online.
|
|
Chatfix 
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Fr 21.10.05 14:02
Also ich habe versucht den Stream mit ZLib zu komprimieren allerdings bringt das nicht einen Byte...
Hier mal der Record und das Array...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| type Datenbank = record ID: String[4]; s1: String[255]; s2: String[255]; s3: String[255]; s4: String[5]; s5: String[255]; s6: String[255]; s7: String[255]; s8: String[255]; s9: String[255]; t1: String[255]; b1: Boolean; d1: TDate; i1: Byte; t2: String[255]; t3: String[255]; b2: Boolean; a1: Array[1..10] of String[15]; a2: Array[1..10] of String[255]; end;
type DatenbankArray =array[0..9999] of Datenbank; |
Über eine bessere Lösung würd ich mich sehr freuen.
Ich versuche auch die Strings von den Längen her noch zu kürzen bzw. zu optimieren.
Ob es nun XML oder ein Anderes Format ist ist erstmal egal.
Ich dachte nur in XML gehts vllt besser.
Ich habe allerdings noch nie etwas mit XML gemacht.
Einen fertigen Code verlange ich sicher nicht, aber vielleicht ein paar schnipsel die mir helfen könnten.
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 26.10.05 09:10
Hallo!
Also wie versprochen hier das Testprogramm mit den vier möglichen Varianten. Bei diesem großen Record kommt allerdings die Methode der eigenen Speichermethode wohl nicht in Betracht, es sei denn, die Strings sind durchschnittlich nur etwa 20 Zeichen lang und nur einzelne größer.
Sehr gut geeignet ist dagegen die Komprimierung. Ich habe einen extrem schnellen Algorithmus verwendet (50 MB komprimieren auf einem 2600er Athlon knapp eine Sekunde). Der ist sogar schneller als das Speichern auf der Festplatte, wodurch das Speichern mit der Komprimierung im abgebildeten Beispiel sogar viermal schneller (und natürlich kleiner) als das normale Speichern ist...
Hier ein Screenshot (liegt auch im Archiv dabei):
www.buchmanager-berl...sim/beispiellauf.bmp
Und das Programm:
www.buchmanager-berl.../recordsimulator.rar
|
|
Chatfix 
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Mi 26.10.05 10:35
Soweit so gut
Schönes Programm. Ich habe nur ein Problem, wenn ich deine EXE aus dem RAR aufrufe funktioniert sie super, wenn ich dein projekt allerdings in Delphi öffne und von dort aus starte erhalte ich beim Start des Benchmarks folgenden Fehler:
Zitat: | ---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt RecSim32.exe ist eine Exception der Klasse EStackOverflow aufgetreten. Meldung: 'Stack-Überlauf'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
--------------------------- |
Leider weiss ich nicht woran dies liegen könnte
Aber trotzdem schonmal danke für deine Mühen 
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 26.10.05 12:09
Nun, das weiß ich schon...
Die Verwaltung der Daten in einem solchen Array ist praktisch nicht möglich, weil der Stack zu groß wird. Ich hab für das Projekt eigentlich schon das Maximum (16 MB) eingestellt, aber bei dirscheint das aus irgendeinem Grund nicht zu gehen, beispielsweise, wenn du das Array vergrößert hast (Ich hatte schon den Maximalwert genommen)...
Was gemacht werden muss, ist eigentlich nur folgendes:
Die Daten können zwar in einem solchen statischen Array in eine Datei geschrieben werden, aber die ist dann halt sehr groß, das hast du ja auch gemerkt.
Nur: Im Arbeitsspeicher wird ja genausoviel benutzt, wenn du alles statisch hast, und zwar wird der Speicher ja sofort benötigt, weil eben das Array und die Record-Größe statisch sind.
Darauf bin ich jetzt nicht weiter eingegangen, das war ja auch nicht deine Frage.
Die Lösung ist relativ einfach (es gibt mehrere Möglichkeiten):
Du kannst zum Beispiel einfach statt alle Daten am Anfang einzulesen, zur Laufzeit auf die Daten zugreifen. Einfach nen Stream, und bei statischen Records (also mit statischen Strings, meine ich natürlich) ist es ja dann kein Problem, die richtige Stelle in der Datei für einen bestimmten Record zu finden.
Ggf. kann dann eine Index-Datei beispielsweise eine Überschrift oder so für jeden Eintrag enthalten, welche dann am Anfang geladen wird, falls nötig.
Hier muss aber temporär die entpackte Datei entweder im Speicher oder auf der Festplatte vorhanden sein (innerhalb der gepackten Datei kommt man an die einzelnen Records ja nicht heran)!
Andere Möglichkeit: Dynamische Strings und meine 4. Möglichkeit benutzen.
Grundsätzlich ist das aber alles etwas problematisch. Bei der Anzahl an Datensätzen, die dann ja auch noch scheinbar alle im Speicher ständig verfügbar sein sollen, wäre wohl eine Datenbank das Sinnvollste. XML bringt da auch keinen Unterschied was dieses Problem angeht.
|
|
Chatfix 
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Mi 26.10.05 12:38
Das Problem ist das das Programm nicht installiert werden soll. Es soll für USB-Sticks sein, und überall wo man es ansteckt sofort nutzbar sein.
Und Datenbanken müssen ja meist immer erst installiert werden. oder irre ich mich da?!
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Mi 26.10.05 12:46
Chatfix hat folgendes geschrieben: | Das Problem ist das das Programm nicht installiert werden soll. Es soll für USB-Sticks sein, und überall wo man es ansteckt sofort nutzbar sein.
Und Datenbanken müssen ja meist immer erst installiert werden. oder irre ich mich da?! |
Es gibt auch Datenbanken, die als Bibliothek in das Programm integriert werden und keine extra Installation benötigen. SQLLite bietet sich da zum Beispiel an. Wie man SQLLite aber am besten mit Delphi benutzt, kann ich dir auch nicht sagen.
Stefan
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 26.10.05 12:46
Chatfix hat folgendes geschrieben: | Und Datenbanken müssen ja meist immer erst installiert werden. oder irre ich mich da?! |
ja, eindeutig! Du darfst nur nicht die BDE oder ähnlichen S*** (Sorry Borland...) benutzen...
Es gibt viele Freeware-Units und Komponenten, die keinerlei Installation brauchen!
Beispielsweise sollte die hier gehen:
www.torry.net/db/dir...ectother/paradox.zip
|
|
Chatfix 
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Mi 26.10.05 15:55
Auch auf die gefahr hin das ich nerve, bin leider in sachen DB total unerfahren...
Bei dem besipiel in der ZIP Kommt folgender Fehler:
Zitat: | [Fehler] PdoxTst.pas(26): Der linken Seite kann nichts zugewiesen werden |
Und zwar an dieser stelle:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TPdox.BtnClick(Sender: TObject); const Pdx: TParadox =nil; var i,j,fnd: Integer; v: Int64; S: String; begin If Pdx=nil Then begin Pdx := TParadox.Create(Self); Pdx.Name := 'MyDB'; end;
[...] |
Ich verstehe den Fehler ja auch, weils oben halt als konstante deklariert wurde.
Zudem hab ich eine weitere Frage, ich habe gehört das für Paradox BDE installiert sein muss. Stimmt das?
Liebe Grüße
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
MSCH
      
Beiträge: 1448
Erhaltene Danke: 3
W7 64
XE2, SQL, DevExpress, DevArt, Oracle, SQLServer
|
Verfasst: Mi 26.10.05 20:18
ich schlage vor, dass du dir nochmal die Struktur als auch die Möglichkeiten der Abspeicherung genau überlegst.
Alleine das sortieren, einfügen und löschen beinhaltet einen nicht zu überschätzenden Overhead. Hinzu kommt,das du statische Daten verwendest, bspw. einen String immer mit der 256 Länge, aber vielleicht nur ein Zeichen drinne stehen wird.
XML wird dir da nicht weiterhelfen, auch weil du dort einige nicht triviale vorkehrungen durchführen müsstest. (Schema erzeugen, Interface erstellen etx). Hinzu kommt der Zugriff via DOM als gute alternative, der auf dem Zielsystem einen IE voraussetzt (oder entsprechende Freeware).
Als erstes wie bereits genannt, variable Längen und das Längenbyte mitschreiben, komprieren etc oder gleich eine entsprechende Datenbank verwenden. Aber dann nicht die Grottenschlechte BDE sondern via ADO auf eine Access-DB. Das ist relativ simple und du kannst auf die daten sogar mit SQL zugreifen. Ado setzt mit MDAC auf dem Zielrechner voraus, was bei Windows-Kisten der fall sein dürfte.
grez
MSch
_________________ ist das politisch, wenn ich linksdrehenden Joghurt haben möchte?
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 27.10.05 12:54
Chatfix hat folgendes geschrieben: | Auch auf die gefahr hin das ich nerve, bin leider in sachen DB total unerfahren... |
Passt schon...
Chatfix hat folgendes geschrieben: |
Bei dem besipiel in der ZIP Kommt folgender Fehler:
Zitat: | [Fehler] PdoxTst.pas(26): Der linken Seite kann nichts zugewiesen werden |
Ich verstehe den Fehler ja auch, weils oben halt als konstante deklariert wurde.
|
Du musst Konstanten als veränderbar definieren, da gibts nen Compilerschalter bzw. eine Projektoption!
{$J+} schaltet veränderbare Konstanten (wie es sie ab Delphi 6 nicht mehr gibt) ab.
Chatfix hat folgendes geschrieben: | Zudem hab ich eine weitere Frage, ich habe gehört das für Paradox BDE installiert sein muss. Stimmt das? |
Wenn du die Komponente meinst, die ich verlinkt hatte, dann nicht.
Es stimmt umgekehrt, dass man über die BDE auf Paradox-DBs zugreifen kann. Aber mit Freeware-Komponenten wie diesen MUSS man eben nicht mehr die BDE benutzen. Diese bieten eine komplett native Alternative an.
Folgende Links führen übrigens zu Source, bei dem nicht nur Paradox, sondern viele Formate möglich sind (insbesondere beim ersten; der zweite ist auch für Delphi 7, da weiß ich aber nicht, was der alles kann)!
www.buchmanager-berl...a/chatfix_db/alp.zip
www.buchmanager-berl...tfix_db/degisydb.zip
(Das biete ich auch als Alternative an, falls du den vorherigen Code nicht mit der neueren Delphi-Version zum laufen bringst. Denn die Konstanten sind ja vielleicht nicht das einzige Problem...)
|
|
Chatfix 
      
Beiträge: 1583
Erhaltene Danke: 10
Win 10, Win 8, Win 7, Win Vista, Win XP
VB.net (VS 2015), MsSQL (T-SQL), HTML, CSS, PHP, MySQL
|
Verfasst: Do 27.10.05 14:07
Ich hab mir jetzt beides angeschaut, gibt ja bei beiden leider kein beispiel...
ich werde das ganze projekt jetzt abbrechen, ich bin wahrscheinlich zu dumm um mit DBs umzugehen...
Trotzdem allen vielen Dank!
_________________ Gehirn: ein Organ, mit dem wir denken, daß wir denken. - Ambrose Bierce
|
|
|