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
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.140 Beiträge
 
Delphi 2009 Professional
 
#1

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

  Alt 5. Apr 2019, 20:38
Platzsparender wäre (falls der Arbeitsspeicher nicht zu fragmentiert ist) TMemoryStream und sich ein TDictionary<Integer, Integer> o.ä. mit Zeilenstartpositionen anzulegen. Da man beim Zeilenstart zwischen ANSI und UTF-8 nicht unterscheiden muss, würde man das Kodieren nach UTF-16LE („WideString“) erst beim Zugriff vornehmen. Schreiben wird aber schwer und insbesondere das Überschreiten von Capacity ein großes Problem.

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.
Janni
2005 PE, 2009 PA, XE2 PA

Geändert von Redeemer ( 5. Apr 2019 um 20:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#2

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

  Alt 5. Apr 2019, 22:13
Platzsparender wäre (falls der Arbeitsspeicher nicht zu fragmentiert ist) TMemoryStream und sich ein TDictionary<Integer, Integer> o.ä. mit Zeilenstartpositionen anzulegen. Da man beim Zeilenstart zwischen ANSI und UTF-8 nicht unterscheiden muss, würde man das Kodieren nach UTF-16LE („WideString“) erst beim Zugriff vornehmen. Schreiben wird aber schwer und insbesondere das Überschreiten von Capacity ein großes Problem.

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.
Ja, stimmt, capacity könnte ich auch sinnvoller vorbelegen...
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#3

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
 
#4

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
TiGü

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

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.561 Beiträge
 
Delphi 12 Athens
 
#6

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
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#7

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
Antwort Antwort


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 16:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz