![]() |
Wie verwalte ich so viele Daten?
Hi,
Ich würde gerne eine Datei nach 4-Byte-Folgen durchsuchen und diese Zählen. Also z.B. wie oft kommt $25$75$DA$2F in Datei.xyz vor. Nur das ich nicht nur 1 4-Byte-Folge zählen will, sondern alle von $00000000 bis $FFFFFFFF... Also bräuchte ich theretisch sowas wie:
Delphi-Quellcode:
Aber das sprengt ja alle Rahmen...
Zaehlarray: Array[0..High(Cardinal)] of Word;
Wie mache ich sowas am besten? Gruß Neutral General |
Re: Wie verwalte ich so viele Daten?
Ein Großteil wird ja garnicht vorkommen. Also nimm statt eines Arrays eine Liste, und füge jede Folge die du neu findest in diese ein. Findest du diese öfter, dann einen Zähler jeweils mit erhöhen.
|
Re: Wie verwalte ich so viele Daten?
Ja dachte ich mir auch schon aber das nachgucken, ob eine Folge schon in der Liste ist, dass dauert ja auch ne Weile... Wird das nicht irgendwann zu aufwendig (CPU)?
|
Re: Wie verwalte ich so viele Daten?
Hallo,
wenn die Liste sortiert ist, dann kannst du mittels binärer Suche sehr effizient zugreifen. Übrigens hat ein Word nur zwei Byte ... Grüße vom marabu |
Re: Wie verwalte ich so viele Daten?
Zitat:
Das ganze sollte ja ungefähr so laufen (theorie)
Delphi-Quellcode:
Gruß
var Arr: Array[0..High(Cardinal)] of Word;
buf: Cardinal; begin stream.LoadFromFile(datei); stream.Read(buf,4); inc(Arr[buf]); Neutral General |
Re: Wie verwalte ich so viele Daten?
Wenn du das nicht mit MMFs machst, bist du verloren.
|
Re: Wie verwalte ich so viele Daten?
Und was sind MMFs ? Mapped Files?
Und wenn ja - wie benutze ich die? |
Re: Wie verwalte ich so viele Daten?
|
Re: Wie verwalte ich so viele Daten?
Hi Michael,
mit zwei Byte zählst du nur bis 64K - das könnte in einigen Fällen zu wenig sein. Dein statisches Array würde in jedem Fall 2^34 Byte (16GB) belegen. Mit einem entsprechenden Server unter 64bit Windows kein Problem - ich beneide dich um deine HW Austattung. Nimm eine TList und erweitere sie um die binäre Suche - besser ist dass. Freundliche Grüße |
Re: Wie verwalte ich so viele Daten?
Ich würde sogar noch weiter gehen, und eine Hashmap verwenden.
![]() Eine binäre Suche dauert doch etwas, wenn auch nicht viel, aber der Suchaufwand nimmt mit der Größe der Liste doch zu. Das passiert bei einer Hashmap nicht. Die Hashmap wächst dynamisch. Bei der o.g. Hashmap (TIntegerDictionary) wird zu jedem 4-Byte Schlüssel eine Nutzerinformation (Pointer) gespeichert. So würde die Zählfunktion aussehen:
Delphi-Quellcode:
Das geht -wie schon erwähnt- sehr schnell, schneller gehts eigentlich nicht (ok, eine Skiplistei ist marginal schneller, wenn sie nicht zu groß wird).
Procedure Count (aDict : TIntegerDictionary; aCardinal : TCardinal);
Var cnt : PInteger; Begin If aDict.Find (aCardinal, Cnt) Then // Wenn schon in der dictionary Cnt^ := Cnt^ + 1 // ... Zähler erhöhen Else Begin new (Cnt); // Ansonsten neuen Zähler anlegen Cnt^:= 1; // Initalisieren aDict.Add (aCardinal, Cnt); // und ab in die dictionary End End; Klitzekleiner Pferdefuß: Die Ergebnisse sind unsortiert, du musst sie am Schluss auslesen, in eine Liste packen und diese dann sortieren, aber das hättest Du bei einer Liste ja auch. |
Re: Wie verwalte ich so viele Daten?
Ich hab mit binärer bzw. arithmetischer Suche in Listen hervorragende Erfahrungen gemacht, auch bei mehreren zigtausend Einträgen. Im Worst-Case bist du da mit einer Suchzeit von O(log(n)) unterwegs, und der WC tritt selten genug auf, bzw. je homogener die Liste, desto seltener.
Vorteil dabei ist zudem, dass eine Suche nach einem Eintrag im Falle des Nichtfindens auch gleich die Position liefert, an der einzufügen wäre um gleich während des Aufbaus die Sortierung zu gewährleisten, und Suchen+Einfügen damit im Grunde ein und die selbe Operation ist, die auch nur ein Mal pro Durchlauf gemacht werden muss. Nach meinem Empfinden ist hier eine Hashtable fast schon Overkill, wenn auch nicht weniger Elegant. Aber ein Array der Länge Max(Cardinal) ist größtmöglicher Unfug ;) |
Re: Wie verwalte ich so viele Daten?
Hi Medium,
guck mal da, und wahrscheinlich wird auch Deine binäre Suche im Nachteil gegenüber Hashtabellen sein ... ![]() Gruss stoxx |
Re: Wie verwalte ich so viele Daten?
Zitat:
Zitat:
Das von stoxx verlinkte Demo-Programm zeigt diese gravierenden Unterschiede (Sorted List = binäre Suche). Bei 1Mo Werten dauert die BS einfach viel zu lange. Für das Verwalten von Schlüssel/Wert-Paare verwende ich ausschließlich Hashmaps (außer bei 20 Einträgen, da reicht auch ne Stringlist). Aber selbstverständlich macht man mit der binären Suche gute Erfahrungen, schließlich funktioniert sie ja. Wie Skiplisten und Hashmaps auch. |
Re: Wie verwalte ich so viele Daten?
Zitat:
Noch schneller wirds wie gesagt mit der arithmetischen Suche, die Wikipedia als ![]() ![]() O(log(log(n))) ist im Falle von n=1000000 ca. 4,3. Schneller ist dann fast nur noch indizierter Zugriff auf ein Array[Cardinal]. Mich würde tatsächlich interessieren, ob ich da nun grundsätzlich was missverstanden habe. :) |
Re: Wie verwalte ich so viele Daten?
Zitat:
Nachteil allerdings, dass Du Dir die "Position" erst berechnen musst. Was also dann letztendlich schneller ist, lässt sich mit theoretischen Methoden dann nur noch bedingt berechnen. Und zeigt am besten ein praktischer Test, und die Demo im Link zeigt das ja eindeutig recht gut, dass ein Hash schneller ist, wenn man denn die Daten nicht sortiert benötigt :-) so ist das eben, mit den Vor und Nachteilen .. je nach Anwendung eben ... |
Re: Wie verwalte ich so viele Daten?
Jau, da wirds dann in der Tat sehr von der Grundmenge und dem Einsatz abhängig. Insbesondere die Frage nach der Sortierung wird dann wohl interessant. Aber gut, der TE hat ja jetzt eine Menge sehr guter Verfahren zur Auswahl, und kann sich dann was passendes aussuchen :)
|
Re: Wie verwalte ich so viele Daten?
Liste der Anhänge anzeigen (Anzahl: 1)
Medion, stoxx ihr habt beide einen Denkfehler.
Meine Beispielrechnung bezog sich -wie beschrieben- auf eine Datei mit 1 Mio 4-Tupeln, die es zu analysieren gilt. Der Einfachheit halber habe ich angenommen, das bei BEIDEN Verfahren bereits 1 Mio Einträge in der Liste enthalten sind. Ansonsten müsste man das nichtlineare Verhalten der binären Suche mit einbeziehen, und das habe ich mir gespart. Insofern stimmt meine Rechnung: Ich muss also bei der BS 1 Mio * 19 Vergleiche machen (für jedes der 1 Mio 4-Tupel im Mittel 19 Vergleiche) , bei der Hashmap eben 'nur' 1,1 Mio. In Wirklichkeit wird der Unterschied vermutlich etwas geringer ausfallen (weil eben die Liste anfangs leer ist), aber es geht ums Prinzip. Einen weiteren Nachteil hat eine sortierte Liste: Man muss beim Einfügen den ganzen Speicher verschieben, also im Mittel die halbe Liste. Das Problem hat man mit einer Hashmap nicht. Zitat:
Zitat:
Die 'Berechung' der Position in der Hashmap ist zudem bei einer Integer-Hashmap ein einziges 'MOD', sodaß man hier nicht gerade von komplexen Berechnungen reden kann... Letztendlich kann man diskutieren und rumrechnen: Die Demo beantwortet alle Fragen. Allerdings verwendet sie Strings als Schlüssel, also sind die Zeiten zwar vergleichbar, aber absolut sollte das schon wesentlich schneller gehen. Auf meinem Laptop dauert mein oben geposteter Code bei 1Mio Elementen 300ms (Mobile Pention 1,5GHz, also ne alte Mühle) Im MS SQL-Server kommt übrigens bei der Verwaltung der freien Speicherblöcke eine Skiplist zum Einsatz, weil sie von der Speicherfragmentierung besser (=besser vorhersagbar) als eine Hashmap ist. [klugscheiss]Hat mir keine Ruhe gelassen, kleine Demo gebaut.... Man sind wir besch**** da rechnen wir mit irgendwelchen O's rum, wo der absolute bottleneck dieses Einfügen in die Liste ist. Beweis: die Demo. Hier kann man zwei Werte angeben: 1. Anzahl der einzufügenden Werte. 2. Anzahl der unterschiedlichen Werte. (for i:=1 to Total do insert (i mod unterschiedlich) Binärsuche kann man total vergessen. Auch jeder andere Algorithmus, der eine statische Liste befüllt, scheidet wohl aus. [/klugscheiss] edit: Demo verbessert: Es werden nun Random-Zahlen (jeweils gleicher RandSeed) gezählt. |
Re: Wie verwalte ich so viele Daten?
Ohne mir die Demo jetzt angesehen zu haben, vermute ich ganz stark auch auf Grund deiner Äusserung, dass man beim Einfügn die halbe Liste verschieben müsste, dass du als Datencontainer ein Array verwendest, vermutlich sogar noch ein dynamisches. Dass dann eine Einfügeoperation um Kardinalitäten langsamer als eine Anfügeoperation ist, sollte einleuchten.
Eine doppelt verkettete echte Liste macht hingegen genau keinen Unterschied dabei, ob ich nun hinten anfüge oder in der Mitte etwas zwischenhänge. Ohne jeweils passende Datenstrukturen nützt der ganze Vergleich leider nichts. Letztlich will ich hier ja garkeinen Flamewar zwischen binärer Suche und Hashmaps anzetteln, sondern nur darauf hinweisen, dass Hashmaps nicht in jedem Fall das nun plus ultra sind. Auch gibt es einen gewissen Overhead, dass in Kollisionsfällen doch wieder Listen zum Einsatz kommen, und damit in sehr degenerierten Fällen eine Hashmap wieder zu einer Liste machen. (Dabei ist dann die Länge des Hashes, also indirekt der Speicherbedarf wieder interessant.) Insbesondere die implizite Sortierung dürfte der binären Suche (bzw. ihren Verbesserungen, die du bislang nicht beachtet hast) einen großen Pluspunkt verschaffen, weil zumindest is sehr vielen Anwendungen mit derart vielen Daten letztlich eine Sortierung mindestens wünschenswert ist (um z.B. Daten in einer bestimmten Range auszugeben etc.). Die Wahl ist daher stark von der Beschaffenheit der Datenmenge, und dem Einsatzzweck abhängig. Allerdings: Zitat:
|
Re: Wie verwalte ich so viele Daten?
Zitat:
Zitat:
Zitat:
Zitat:
Ich kann jedoch einen theoretische Worstcase konstruieren, wenn ich die Hash-Funktion der Hashmap kenne, und dafür sorge, das meine Schlüssel immer auf dem gleichen Bucket landen. Dieser Worstcase kommt aber in der Realität eigentlich nie vor. Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Bei den von Dir erwähnten Verbesserungen hätte man weniger Vergleiche, aber *immer* mehr als bei einer Hashmap. Weiterhin kenne ich keine Implementierung, die eine der erwähnten Suchverfahren auf einer verketteten Liste anwenden kann, wir haben es hier also letztendlich mit Arrays zu tun, die dann nicht zu gebrauchen sind. Natürlich sind deine Überlegungen bezüglich des WC richtig, aber wenn der WC in der Praxis nicht vorkommt, dann ist das irrelevant. Jede Hash-Funktion hat einen WC (zwei Strings mappen auf den selben Wert). Werden sie deshalb nicht eingesetzt? Jeder Quicksort auch. Trotzdem verwendet man ihn. Und eine Hashmap hat einen extrem lahmen Worst Case, trotzdem sind die Teile im Einsatz, wie eben ein Quicksort oder ein KMP-Search etc. Meine Demo simuliert die vom Fragesteller thematisierte Problematik: Es werden Häufigkeiten gezählt. Da interessiert mich irgend ein Worst Case oder eine theoretische Berechnung nicht. Ich starte und schaue auf das Ergebnis. In der ersten Version habe ich einfach aufsteigend die 'i mod X' gezählt, das führt bei der BS zum Worst Case und ist insofern unfair. Also habe ich eine neue Version eingestellt, die Zufallszahlen (jeweils mit gleichem Seed) zählt. Die Ergebnisse sind immer noch so, das man das BS letztendlich in die Tonne treten kann. Wenn Du natürlich eine deiner Suchverfahren mit einer verketteten Liste durchführen kannst, wäre das Ergebnis zwar immer noch langsamer als eine Hashmap, dafür hätten wir aber eine Struktur mit einem akzeptablen weil deterministischen Worst Case. Diese Implementierung würde ich dann als akzeptable Alternative zu Hashmaps, Skiplisten, DAWGs etc. ansehen. |
Re: Wie verwalte ich so viele Daten?
Zitat:
1) Ein Verweis-Array mitführen (was jedoch selbst dann das Problem hat, dass es Verschiebungen darin gibt. Es lohnt also nur, wenn die Daten erheblich länger ausfallen und somit beim Umkopieren ein echter Unterschied existiert) 2) In Schleifchen durchhangeln. Klingt zunächst suboptimal, ist aber schnell genug, da man bedenken muss, dass man sich pro Iterationschritt nur noch maximal um die Hälfte nochmal hangeln muss, bzw. bei den verbesserten Versionen nochmals weniger. So mache ich es in einem Programm, bei dem eine Liste von rund 30 Mio Punkten im Raum verarbeitet wird, und ich bin eigentlich recht zufrieden mit der Geschwindigkeit. Wenn ich Zeit und Muße hab, werd ich das mal testweise mit einer Hashmap bauen. Zitat:
Zitat:
Zitat:
Zitat:
Dass Hashmaps zur Verwaltung von Strings eigentlich immer überlegen sind kann ich gut nachvollziehen, und in diesem Zusammenhang hab ich sie auch bisher nur gesehen. Bei numerischen bzw. binären Werten sind sie mir eigentlich noch nicht über den Weg gelaufen. |
Re: Wie verwalte ich so viele Daten?
Hi Medium,
Zitat:
Zitat:
Zitat:
. Zitat:
|
Re: Wie verwalte ich so viele Daten?
och kommt jetzt, medium meint sicherlich 'n binary tree, statt 'ner verketteten liste :-) . ausserdem geb ich alzaimar recht, dass es nichts schnelleres gibt, als 'ne hash-verwaltung :-)
nur, frag ich mich, wie Neutral General hieraus konsequenzen ziehen soll, um zu wissen, wie er jetzt seine 4 bytes ablegen soll. so denn, noch 'n schönen abend. :-) GG btw: ist immer nett experten beim fachsimplen zuzuhören :-) |
Re: Wie verwalte ich so viele Daten?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:55 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