AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)
Thema durchsuchen
Ansicht
Themen-Optionen

Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

Ein Thema von Harry Stahl · begonnen am 5. Apr 2019 · letzter Beitrag vom 17. Apr 2019
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 6. Apr 2019, 11:56
Wie entwickeln Datenbanken die auch mal mehrere Milliarden Datensätze enthalten können. Unser System ist zwar multidimensional aufgebaut aber die Probleme sind wahrscheinlich ähnlich. Es hat sich gezeigt, das die Standardkomponenten wie TStringList, TDictionary usw. für so etwas nicht ausgelegt sind. Auch Tricks wie TList.Capacity bringt nicht viel. Deshalb wurde alles ziemlich weit unten neu "aufgebaut". Auch auf TObject wurde verzichtet, da der Overhead (Geschwindigkeit und Speicher) im Vergleich zu TRecord zu groß ist. D.h. es blieb nur noch TRecord, Arrays, Pointer und selber QuickSort Routinen schreiben (zum Suchen und Einfügen). Und an einigen kritischen Stellen ASM verwenden. Damit läuft es aber sehr ordentlich. Also eher "back to the basics"
Ja, danke das sind Erfahrungsberichte, die ich sehr interessant finde. Habe mir schon so was gedacht.

Wie gesagt, meine jetzige Lösung ist nur eine "kleine" Lösung, aber für die Version 5 im nächsten Jahr will ich dann doch auch große Datenmengen (> 100 Mio. oder mehrere Mrd) zügig verarbeiten können.

Habt Ihr dann ganz auf die "typischen" SQL-DB's verzichtet und eine eigene Lösung gebastelt?

Und selbst das TDictionary haltet Ihr nicht für geeignet? Wegen des Anlegens der Sammlung oder Speicherverbrauch? An der Geschwindigkeit könnte es doch eher nicht liegen, oder?

Die vorgetragenen Argumente pro SQL sind mir alle einleuchtend, dennoch hänge ich ein wenig an eigenen Lösungen, da die oft sehr viel mehr Flexibilität für "Sonderwünsche" bieten.
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.468 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#12

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 6. Apr 2019, 12:46
Wenn in den Daten viele Strings doppelt vorkommen, hilft vielleicht String Interning. Das hat mir mal sehr geholfen, den Speicherbedarf einer Anwendnung zu reduzieren. Dadurch werden doppelte Strings zu einem einzigen zusammengefasst, der dann entsprechnend einen höheren Referenzzähler hat.

Eine Implementation auf Basis einer Stringlist findest Du z.B. in meiner dzlib. Die ist allerdings noch für AnsiStrings entwickelt und mit UnicodeStrings nicht getestet.
Thomas Mueller
  Mit Zitat antworten Zitat
Thomas Horstmann

Registriert seit: 25. Apr 2007
86 Beiträge
 
Delphi 10.3 Rio
 
#13

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 6. Apr 2019, 12:52
Unsere Datenbank ist multidimensional und da läuft die Speicherung anders wie in der relationalen Wert. Eine Tabelle besteht nicht aus einem großen "Array", sondern aus viele kleinen, die untereinander per Pointer verbunden sind. Ggf. werden diese Konstrukte dann Milliarden mal durchlaufe, so dass es "unten" auf jedes if/then/else ankommt. Und 10% mehr Speicher oder weniger Geschwindigkeit ist dann schon ein Ausschlusskriterium. Wir haben einiges getestet und alles ab TObjekt war nicht brauchbar.

Aber das ist auch der Vorteil von Delphi; es ist relativ alt und systemnah. Strukturen wie Array, Pointer, Record usw. kommen aus einer Zeit als CPU und Speicher knapp waren. Da musst alles extrem optimiert werden. Und dem Kunden heute kann es "grundsätzlich" nie schnell genug gehen.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 10. Apr 2019, 21:06
Wenn in den Daten viele Strings doppelt vorkommen, hilft vielleicht String Interning. Das hat mir mal sehr geholfen, den Speicherbedarf einer Anwendnung zu reduzieren. Dadurch werden doppelte Strings zu einem einzigen zusammengefasst, der dann entsprechnend einen höheren Referenzzähler hat.

Eine Implementation auf Basis einer Stringlist findest Du z.B. in meiner dzlib. Die ist allerdings noch für AnsiStrings entwickelt und mit UnicodeStrings nicht getestet.
Interessante Idee, nur kommen hier im Prinzip keine doppelten Strings vor, da jeder String mit einem eindeutigen ID versehen ist (somit ist jeder String anders).

Aber dennoch interessant, evtl. kann man es ja mal bei einer anderen Gelegenheit verwenden.

Geändert von Harry Stahl (10. Apr 2019 um 21:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#15

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 10. Apr 2019, 21:35

Vermutlich ebenfalls möglich wäre ein TFileStream (oder TStringReader, wenn der intern auch so funktioniert), der die Dinge in einem Array von RawBawbyteString ablegt, grundsätzlich wäre es aber gut, die Zeilenzahl zu kennen.
Tfilestream zu verwenden war eine gute Idee fürs Laden und Speichern der eigenen Datendatei, da ich so das zusätzliche Anlegen von großen TMemorystreams vermeiden kann. Wenn die DB verschlüsselt ist, muss ich allerdings doch wieder TMemorystream verwenden, da das verschlüsseln und entschlüsseln auf einem TFilestream zu langsam ist. Letztlich aber nicht so schlimm, da ich die Verschlüsselung immer nur auf eine komprimierte Datei anwende, die ist deutlich kleiner als die eigentliche Datenmenge und das dekomprimieren der entschlüsselten Datei geht zügig genug mit dem Filestream.

Mit den ganzen Optimierungen ist es mir jetzt immerhin gelungen (in der Windows 64-Bit bzw. Linux-64-Bit-Version mit mindestens 16 GB RAM) die 2,1 GB große csv-Datei mit über 15 Mio. Datensätzen zu importieren und in meinem komprimierten Datenformat zu speichern (dann werden da ca. 600 MB draus). Wie gesagt, arbeiten kann man damit dann nicht mehr flüssig (z.B. die "Life"-Filterung wird dann extrem hakelig und laden und speichern dauert z.B. einige Sekunden), also nach wie vor bleibt es bei der Zielgruppe der User, die nicht mehr als 100.000 - 200.000 DS mit dem Programm bearbeiten müssen. Hat aber einfach Spaß gemacht, die Leistungsgrenzen mal ein wenig aufzubohren und ein wenig mehr Gefühl dafür zu bekommen, bei welchen Aktionen u.U. schnell ein großer Speicherverbrauch auftreten kann.

Letztlich hat das auch dazu geführt, dass ich unter Windows erstmals eine 64-Bit-Version eines Programm veröffentlicht habe, denn mit dem Wegfall der 2 GB Speichergrenze in der 64-Bit-Programmfassung kommt man in diesem Fall dann doch deutlich weiter... (wäre schön, wenn Delphi - das ja auch noch ein 32-Bit-Programm ist - da gleichfalls mal bald nachziehen würde...)

Geändert von Harry Stahl (10. Apr 2019 um 21:54 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#16

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 11. Apr 2019, 07:13
Also erstmal mein Kompliment zur Optimierung der Anwendung. Diese Mühen nimmt selten jemand auf sich. Der Anlaß trübt allerdings meine Begeisterung etwas. Ich hab zu dem Thema "3" Punkte:
- Bei Deinen Optimierungen sollte Dir klar sein, dass Deine Anwendung ggF. nicht die einzige auf dem PC ist. Datensatzzahlen bzw. Verarbeitungsgeschwindigkeit sind also vielleicht trügerisch.
- Zum empfohlenen Einsatz von Datenbanken und deinen Worten von der Verarbeitung von Milliarden Datensätzen: Der Einsatz einer DB Engine macht aus einem Desktop (oder Racksystem) keinen Quantencomputer. Das Prinzip beruht hauptsächlich auf der gezielten und kleinteiligen Verarbeitung eines Datenausschnitts. Also große "Festplatte", optimierter Zugriff, kleine OPs. Solltest du wirklich in die Verlegenheit kommen, Milliarden Daten zu >verarbeiten<, wirst Du schnell die Grenzen dieser Systeme kennenlernen.
- SQL als Standard ist leider schwierig. Sobald Du in der Anwendung Query Komponenten verwendest, kommt wahrscheinlich irgendwann der Punkt, wo Du proprietäre Syntax verwendest, besonders bei der "Verarbeitung von Milliarden DS". Performancebedarf wird in SQL häufig mit proprietären Lösungen gedeckt. Allein die Vielfalt der existierenden Systeme (Deins inkl.) und die Verschiedenheit der Ansätz (noSQL, ..) spiegeln den recht unterschiedlichen Bedarf und eben die Lösungswege.
- CSV kann heute fast jede DB Engine von sich aus einlesen.

Ich habe bei der Schilderung deiner Situation an ORM Systeme denken müssen. Damit kannst Du vielleicht eine ggute Trennschicht zwischen Dein (gewohntes) System und die DB ziehen. Außerdem musste ich an die Arbeit von @haentschman denken, mit ihm solltest du vielleicht mal ein Bier trinken gehen.
Gruß, Jo
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#17

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 11. Apr 2019, 08:06
Zitat:
Das ist natürlich schon klar, dass ich mit einer "echten" leistungsfähigen Datenbank-Engine ganz andere Sachen machen kann (wenn man sich denn damit auskennt, das ist ja bei mir das bekannte "Schwarze Loch").
Dann bleibe ja noch der Zwischenweg: ORM. Der Zugriff auf Datenbanekn über Nicht-Datenbank-Strukturen.
Markus Kinzler
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.062 Beiträge
 
Delphi 10.4 Sydney
 
#18

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 11. Apr 2019, 08:16
Du könntest noch ein bisschen mit der neuen Möglichkeit spielen, deine eigene Wachstumsstrategie für Collection-Klassen zu implementieren.
Wenn dir im Vorfeld die maximale Größe der Datenstrukturen bekannt ist und du die vor dem Füllen setzen kannst, dann kannst du das neu allozieren und umkopieren des darunterliegenden Arrays im Grenzbereich sparen.
Ein paar Prozent mehr Speicheroptimierung und/oder Performance lässt sich vielleicht rausschinden.

http://blog.marcocantu.com/blog/2018...ments-rio.html
http://docwiki.embarcadero.com/Libra...CollectionFunc
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#19

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 12. Apr 2019, 14:54
Also erstmal mein Kompliment zur Optimierung der Anwendung. Diese Mühen nimmt selten jemand auf sich. Der Anlaß trübt allerdings meine Begeisterung etwas. Ich hab zu dem Thema "3" Punkte:
- Bei Deinen Optimierungen sollte Dir klar sein, dass Deine Anwendung ggF. nicht die einzige auf dem PC ist. Datensatzzahlen bzw. Verarbeitungsgeschwindigkeit sind also vielleicht trügerisch.
- Zum empfohlenen Einsatz von Datenbanken und deinen Worten von der Verarbeitung von Milliarden Datensätzen: Der Einsatz einer DB Engine macht aus einem Desktop (oder Racksystem) keinen Quantencomputer. Das Prinzip beruht hauptsächlich auf der gezielten und kleinteiligen Verarbeitung eines Datenausschnitts. Also große "Festplatte", optimierter Zugriff, kleine OPs. Solltest du wirklich in die Verlegenheit kommen, Milliarden Daten zu >verarbeiten<, wirst Du schnell die Grenzen dieser Systeme kennenlernen.
- SQL als Standard ist leider schwierig. Sobald Du in der Anwendung Query Komponenten verwendest, kommt wahrscheinlich irgendwann der Punkt, wo Du proprietäre Syntax verwendest, besonders bei der "Verarbeitung von Milliarden DS". Performancebedarf wird in SQL häufig mit proprietären Lösungen gedeckt. Allein die Vielfalt der existierenden Systeme (Deins inkl.) und die Verschiedenheit der Ansätz (noSQL, ..) spiegeln den recht unterschiedlichen Bedarf und eben die Lösungswege.
- CSV kann heute fast jede DB Engine von sich aus einlesen.

Ich habe bei der Schilderung deiner Situation an ORM Systeme denken müssen. Damit kannst Du vielleicht eine ggute Trennschicht zwischen Dein (gewohntes) System und die DB ziehen. Außerdem musste ich an die Arbeit von @haentschman denken, mit ihm solltest du vielleicht mal ein Bier trinken gehen.
Ja, das mit den Mrd. Datensätzen war vielleicht auch ein wenig hoch gegriffen...

SQL finde ich sehr interessant, wie man mit recht einfachen Sprachkonstrukten Auswahlen von Daten bzw. neue Tabellen anlegen kann. Sehr schön, schon beschlossene Sache, dass ich in Version 5 die wesentlichen SQL-Befehle als Alternative zu meiner eigenen Lösung unterstützen werde.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.479 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: Kodieren gegen großes Datenvolumen (Datendatei > 2 GB, > 15 Mio. DS)

  Alt 12. Apr 2019, 15:03
Du könntest noch ein bisschen mit der neuen Möglichkeit spielen, deine eigene Wachstumsstrategie für Collection-Klassen zu implementieren.
Wenn dir im Vorfeld die maximale Größe der Datenstrukturen bekannt ist und du die vor dem Füllen setzen kannst, dann kannst du das neu allozieren und umkopieren des darunterliegenden Arrays im Grenzbereich sparen.
Ein paar Prozent mehr Speicheroptimierung und/oder Performance lässt sich vielleicht rausschinden.

http://blog.marcocantu.com/blog/2018...ments-rio.html
http://docwiki.embarcadero.com/Libra...CollectionFunc
In Delphi 10.3 ist wohl "Dictonary.Tryadd" neu / optimiert worden, bringt noch 100-200 ms bei ca. 2 Mio DS (statt if not Dictionary.contains, then add).

Was ich festgestellt habe, was viel Zeit kostet, ist die Sortierung der Stringlisten, wenn nach Textinhalten sortiert werden soll. Insbesondere, wenn (was ja Standard ist) Stringlist.uselocale auf True ist. Bei deutschen Textinhalten (Umlaute!) braucht man das aber leider, kann man aber ausschalten, wenn nur auf ein Integer-Feld sortiert wird und keine 2 oder 3. Text-Sortierfeld verwendet wird.

Wenn .Uselocale aktiv ist, wird in "TStrings.Comparestrings" die Funktion "AnsiCompareText" (statt sonst "CompareText") verwendet, was recht langsam ist (12 Sekunden, statt 4 Sekunden mit CompareText).

Gibt es dazu keine bessere Lösung?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz