![]() |
AW: Schnittmenge von mehreren Mengen ermitteln
Bin mal gespannt, wie schnell ihr mit eurem Rumgehüpfe seid. ;-)
|
AW: Schnittmenge von mehreren Mengen ermitteln
Moin,
Zitat:
Einzelne Schlüssel zu lesen, bremst ziemlich aus. Das wurde hier gut beschrieben: ![]() |
AW: Schnittmenge von mehreren Mengen ermitteln
Wie wäre es mit einer Kombination?
Erstmal die zwei kleinsten Dateien in den Speicher laden, und die Schnittmenge bilden. (Mit zwei Indizes, wie von generic erklärt) Danach immer die nächste Datei in den Speicher laden und die bisherigen Einträge per binärer Suche in der Datei suchen. Das laden der Datei könnte man noch in einen Thread auslagern. Ist aber fraglich ob sich das lohnt - die Datenmenge klingt nach einer Rechenzeit von 300ms. Die Synchronisation von Threads könnte das schon wieder verlangsamen. Damit sollte die Schnittmenge schnell kleiner werden (damit die binäre Suche flott ist) aber am Anfang dürfte das Verfahren mit den zwei Indizes besser sein. Und solange es geht immer im RAM arbeiten, und keine einzelnen Werte von der Platte lesen! Damit kann man jeden Algorithmus zum Schneckentempo zwingen. (ggf. ein Bandlaufwerk in Erwägung ziehen....) |
AW: Schnittmenge von mehreren Mengen ermitteln
Bei Sprüngen würde ich mit Memory Mapped Files arbeiten. Damit überlässt du das Lesen aus der Datei dem Betriebssystem und das ist ein Bereich, in den die Betriebssystemler ewig rumoptimieren. Davon kannst du nur profitieren.
Deshalb könnte das auch einen Geschwindigkeitsschub geben, wenn du einen Ansatz ohne Sprünge wählst. Ich persönlich würde allgemein einen der Ansätze wählen, die die Dateien gleichzeitig fortlaufend durchgehen. Aber mit den fortlaufenden Zahlen könntest du den Aufwand vermutlich auf die Größe der kleinsten Datei drücken, mehr Informationen (oder vielleicht ein Beispiel) wären schön. |
AW: Schnittmenge von mehreren Mengen ermitteln
Also wenn ich es richtig verstehe ist das, was du willst, ein „Inner-Join“, um es mit SQL-Vokabular auszudrücken. Man könnte also mal recherchieren, welche Algorithmen ausgereifte Datenbanksysteme dafür benutzen. Auf die Schnelle habe ich folgenden gefunden:
![]() Btw, Herumspringen und mit MMFs arbeiten, ist irgendwie witzlos - denn was macht das MMF? Richtig, es liest die Datei in größeren Blöcken ein und kopiert sie in den RAM – und somit liest du im Endeffekt auch wieder die ganze Datei ein, nur hast du dabei noch zusätzlichen Verwaltungs-Overhead. MMFs sind ja eigentlich eher eine Notlösung dafür, wenn man in großen Daten herumspringen muss. Aber wenn man schon die Möglichkeit hat, die Datei in einem Rutsch einzulesen, spricht aus meiner Sicht nichts für ein MMF. MMFs können noch so schnell sein, schneller als das Einlesen in einem Rutsch können sie zumindest bei herkömmlichen Festplatten nicht sein. Allgemein würde ich auch nicht zu viel Hirnschmalz auf dieses Problem verwenden. Ich denke, mit Hashmaps bist du hier erst mal ganz gut bedient. Wenn das wider Erwarten nicht der Fall sein sollte, kannst du dir ja immer noch was besseres überlegen. |
AW: Schnittmenge von mehreren Mengen ermitteln
Ich weiß nicht, was die Hashtable in diesem Fall für Verbesserungen bringen soll. Für die build-Phase muss die kleinste Datei einmal ganz gescannt werden, für die probe-Phase die anderen.
Die Hashtable würde nur dann Sinn machen, wenn die Datensätze nicht sortiert wären. PS: Ich würde noch gerne mehr über die fortlaufenden Nummern erfahren. Meint "fortlaufend" Zahlen in der Form: n, n+1, n+2, n+3, ..., n+m? |
AW: Schnittmenge von mehreren Mengen ermitteln
Zitat:
|
AW: Schnittmenge von mehreren Mengen ermitteln
Zitat:
Kann es jemand schneller? Bei Interesse an einem 'Wettbewerb' poste ich gerne mein Testprogramm. Ich würde allen vorschlagen, weniger über die Theorie zu sinieren, als einfach ein Proof-Of-Concept zu präsentieren. Ich weiss nur, das das Einlesen einer Zahl genauso lange dauert, wie 2000 (Systempage = 8k, 4Byte=eine Zahl) Also wieso sollte ich einzelne Zahlen einlesen und wie soll das gehen? Ich will ja nicht eine Zahl finden, sondern die Schnittmenge über alle Zahlen. Also muss ich auch alle einlesen (nun ja, bis MAX(Bisherige-Schnittmenge)). Ich behaupte mal, das bis -sagen wir- 500MB pro Datei ist das einmalige (schlürf) Einlesen aller Werte bedeutend performanter als Gehirnakrobatik. Aber bitte sehr: 500ms sind zu schlagen :stupid: |
AW: Schnittmenge von mehreren Mengen ermitteln
@Furtbichler
Ich finde gerade weder Zeit noch Muße etwas derartiges zu testen. Ich würde aber da die Daten bereits sortiert sind, vermuten dass Dein Ansatz, den ich bis dahin teile durch ersetzen des Blocks bei " while (j < n) and (Intersect[j] < data[i]) do inc(j);" durch eine BinarySearchfunktion nochmals deutlich am Performance zulegen sollte. |
AW: Schnittmenge von mehreren Mengen ermitteln
Moin,
Zitat:
Erst hatte ich den Verdacht, dass Plattenzugriffe einfach nur "wegdefiniert" werden. :x Nach näherer Betrachtung scheint es aber richtig, zumindest die einzelnen Dateien komplett einzulesen. :shock: Erst mal ein paar Annahmen für Lesezugriffe: HDD: ca. 50 MB/s, 10 ms Zugriffszeit, max. 2 TB für das Programm, das wird nicht eng SSD: ca. 300 MB/s, < 1 ms, keine Kapazität für dieses Programm RAM: ca. 10.240 MB/s, Nanosekundenbereich, max. 20 GB für dieses Programm, RAM, Ramdisk oder Festplattenpuffer Gehen wir mal davon aus, dass es ca. 1 Sekunde dauert, bis 5.000.000 Schlüssel aus einer Datei eingelesen wurden. In dieser Zeit könnte man sich nur ca. 100 mal "Rumgehüpfe" à 10 ms beim erstmaligen Einlesen leisten. In meinem Beispiel benötigt man 11.500 mal. Das wird vermutlich selbst dann nicht schneller als das Einlesen, wenn man davon ausgeht, dass ein Großteil der Anfragen aus Festplattenpuffern des Betriebssystems bedient werden können. Ein "Rumgehüpfe" im RAM könnte auch ein Schuss nach hinten sein. Das überlege ich mir noch. Eine gute Idee finde ich, Dateien im Thread zu lesen. Mehr als 1 zur Zeit schient mir auch nicht sinnvoll. Memory Mapped Files scheint mir auch eher ungünstig. Zu ![]() @Furtbichler Wie hast Du bei Deinem Test sichergestellt, dass Du die Dateien nicht aus dem Puffer des Betriebssystems liest? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:47 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 by Thomas Breitkreuz