![]() |
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. |
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