Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   FreePascal Wo binäre Suche schneller, mit Array oder StringList? (https://www.delphipraxis.net/185048-wo-binaere-suche-schneller-mit-array-oder-stringlist.html)

AlexII 11. Mai 2015 13:50

Wo binäre Suche schneller, mit Array oder StringList?
 
Hallo,

ich möchte Daten (DateTime) aus ner SQLite DB in irgendein Objekt laden und binär durchsuchen. Wie mache ich das am schnellsten? Die Daten in Array oder StringList laden, was ist schneller?

Danke!

Namenloser 11. Mai 2015 14:08

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Das Array sollte schneller sein als die Stringlist. Aber meiner Meinung nach ist beides unsinnig.

Mit Abstand am schnellsten sollte es sein, die „Suche“ einfach in SQL zu formulieren und die Datenbank ihre Arbeit machen zu lassen.

AlexII 11. Mai 2015 14:15

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Namenloser (Beitrag 1301037)
Das Array sollte schneller sein als die Stringlist. Aber meiner Meinung nach ist beides unsinnig.

Mit Abstand am schnellsten sollte es sein, die „Suche“ einfach in SQL zu formulieren und die Datenbank ihre Arbeit machen zu lassen.

Ok... also es ist folgendes, es geht um einen Wecker. Dieser soll nach mehreren (Hunderte, oder Tausende) Terminen "Ausschau" halten, und bei angegebener Zeit Alarm schlagen. Das heißt, dass ich jede Sekunde die aktuelle Uhrzeit mit der in der DB vergleichen muss. Nun suche ich wie ich das am besten mache. Eine binäre Suche wäre schon sinnvoll, oder?

p80286 11. Mai 2015 14:22

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Warum willst Du suchen?
Eine Liste mit dem kleinsten Element (das in der Zukunft liegt) als erstes Element und gut ist.

Gruß
K-H

Zoot 11. Mai 2015 14:23

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Verstehe ich die Aufgabe richtig?
Da bräuchtest du doch nur einmal den nächsten Termin suchen, und vorher gar nicht mehr nachschauen?

jobo 11. Mai 2015 14:25

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von AlexII (Beitrag 1301039)
Ok .. einen Wecker. Dieser soll nach mehreren (Hunderte, oder Tausende) Terminen "Ausschau" halten, und bei angegebener Zeit Alarm schlagen. Das heißt, dass ich jede Sekunde die aktuelle Uhrzeit mit der in der DB vergleichen muss.

Wie wäre es, in der DB die bevorstehenden Minuten sortiert abzufragen und abzuarbeiten? Sind es dann immer noch tausende oder sind es insgesamt tausende?

AlexII 11. Mai 2015 15:04

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von jobo (Beitrag 1301044)
Zitat:

Zitat von AlexII (Beitrag 1301039)
Ok .. einen Wecker. Dieser soll nach mehreren (Hunderte, oder Tausende) Terminen "Ausschau" halten, und bei angegebener Zeit Alarm schlagen. Das heißt, dass ich jede Sekunde die aktuelle Uhrzeit mit der in der DB vergleichen muss.

Wie wäre es, in der DB die bevorstehenden Minuten sortiert abzufragen und abzuarbeiten? Sind es dann immer noch tausende oder sind es insgesamt tausende?

Also Theoretisch können es schon hunderte oder tausende auf ein Schlag sein.

AlexII 11. Mai 2015 15:06

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Zoot (Beitrag 1301043)
Verstehe ich die Aufgabe richtig?
Da bräuchtest du doch nur einmal den nächsten Termin suchen, und vorher gar nicht mehr nachschauen?

Jah.. die Termine können beliebig zerstreut sein, ich muss schon jede Sekunde nach nem Termin schauen.

AlexII 11. Mai 2015 15:07

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von p80286 (Beitrag 1301041)
Warum willst Du suchen?
Eine Liste mit dem kleinsten Element (das in der Zukunft liegt) als erstes Element und gut ist.

Gruß
K-H

Hm... stimmt, muss aber trotzdem oft, jede Sekunde selecten. Ist es sinnvoll die DB jede Sekunde abzufragen?

Neutral General 11. Mai 2015 15:10

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Es ist doch trotzdem am einfachsten sich von der DB eine sortierte Liste aller (bzw. der ersten N) Termine ausgeben zu lassen.
Die kannst du dann ggf. einfach in dieser Reihenfolge in eine Liste schreiben und bei jedem Tick durchläufst
du die Liste von 0 bis zum ersten Termin der noch nicht eingetreten ist, tust was du tun musst für diese Termine
und löschst die abgearbeiteten Termine aus der Liste (und der DB).

Wie schon oben angedeutet: Du musst nicht jede Sekunde die DB abfragen. Wenn du dir alle (oder zumindest nen guten Vorrat) der
nächsten Termine zurückgeben lässt brauchst du nur am Anfang 1x oder ggf. nach ein paar Minuten/Stunden wenn die Liste leer ist/wird
deine Liste mit neuen Terminen auffüllen.

Zacherl 11. Mai 2015 15:12

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Nach gefilterter SQL Abfrage noch 100-1000? :shock:

Naja, solange es nicht über 100.000 werden, würde ich einfach alles in ein Array packen und danach immer sequenziell suchen. Wenn du deine SQL Abfrage nämlich so formulierst, dass die Termine nach Zeit sortiert zurückgegeben werden, dürfte die Suche schon nach sehr wenigen Elementen entweder die gesuchte Zeit gefunden haben, oder aber an einem Element angelangt sein, dessen Zeit größer der aktuellen Zeit ist (an dieser Stelle kannst du die Iteration dann abbrechen).

Immer wenn du einen Termin erfolgreich gefunden und abgearbeitet hast, erhöhst du einen internen Zähler um 1. Diesen Zähler nimmst du jeweils als Start-Index der Array Suche.

bernau 11. Mai 2015 15:13

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Müsstest du nicht auch berücksichtigen, daß neue Termine in die Datenbanke eingetragen werden? Kann das passieren? Wenn ja, dann müsstest du sowiso die Datenbank sekündlich abfragen.

Wenn du nicht damit rechnen musst, daß jemand anderes einen Termin einträget, dann könntest du ja die Termine der nächsten 60 Sekunden abfragen und dann nach 60 Sek. wieder. Wieviel Termine könnten in 60 Sek vorkommen?

AlexII 11. Mai 2015 15:14

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Neutral General (Beitrag 1301051)
Es ist doch trotzdem am einfachsten sich von der DB eine sortierte Liste aller (bzw. der ersten N) Termine ausgeben zu lassen.
Die kannst du dann ggf. einfach in dieser Reihenfolge in eine Liste schreiben und bei jedem Tick durchläufst
du die Liste von 0 bis zum ersten Termin der noch nicht eingetreten ist, tust was du tun musst für diese Termine
und löschst die abgearbeiteten Termine aus der Liste (und der DB).

Wie schon oben angedeutet: Du musst nicht jede Sekunde die DB abfragen. Wenn du dir alle (oder zumindest nen guten Vorrat) der
nächsten Termine zurückgeben lässt brauchst du nur am Anfang 1x oder ggf. nach ein paar Minuten/Stunden wenn die Liste leer ist/wird
deine Liste mit neuen Terminen auffüllen.

Meine Idee war so ähnlich... wollte nur wissen in welche Liste ich die sortierte Abfrage packen soll? TList vielleicht? Welche passt dazu am besten?

Zacherl 11. Mai 2015 15:16

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von bernau (Beitrag 1301054)
Wieviel Termine könnten in 60 Sek vorkommen?

Unendlich viele, wenn man mehrere Termine zur selben Zeit anlegen kann :twisted:

Zitat:

Zitat von AlexII (Beitrag 1301055)
wollte nur wissen in welche Liste ich die sortierte Abfrage packen soll? TList vielleicht? Welche passt dazu am besten?

Ich würde ein Array of TMyRecord nehmen. TList geht natürlich auch, aber dann musst du alle deine Records/Objekte zur Laufzeit noch Heap-allocen, während du beim Array direkt den kompletten Speicherbereich in einem Rutsch reservierst.

AlexII 11. Mai 2015 15:16

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von bernau (Beitrag 1301054)
Müsstest du nicht auch berücksichtigen, daß neue Termine in die Datenbanke eingetragen werden? Kann das passieren. Wenn ja, dann müsstest du sowiso die Datenbank sekündlich abfragen.

Das muss ich natürlich auch beachten. Neue Termine können jede Zeit neu angelegt werden. Heißt also doch die DB jede Sekundlich abfragen! Oder nach Schreibvorgängen schauen, falls ein Schreibvorgang stattfindet die Termine neu laden.

Zacherl 11. Mai 2015 15:20

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von AlexII (Beitrag 1301058)
Zitat:

Zitat von bernau (Beitrag 1301054)
Müsstest du nicht auch berücksichtigen, daß neue Termine in die Datenbanke eingetragen werden? Kann das passieren. Wenn ja, dann müsstest du sowiso die Datenbank sekündlich abfragen.

Das muss ich natürlich auch beachten. Neue Termine können jede Zeit neu angelegt werden. Heißt also doch die DB jede Sekundlich abfragen! Oder nach Schreibvorgängen schauen, falls ein Schreibvorgang stattfindet die Termine neu laden.

Wenn du eh sekündlich ne Query raushauen musst, dann kannst du die Ergebnisse ja sogar ganz konkret bis auf die Sekunde genau filtern lassen. In dem Falle brauchst du gar nichts in ein Array oder eine Liste zuwischenspeichern.
Du weißt ja in diesem Falle genau, dass alle zurückgelieferten Einträge genau jetzt in diesem Moment ein Ereignis auslösen müssen. Dazu iterierst du dann einfach über das SQLResult.

AlexII 11. Mai 2015 15:22

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Zacherl (Beitrag 1301061)
Zitat:

Zitat von AlexII (Beitrag 1301058)
Zitat:

Zitat von bernau (Beitrag 1301054)
Müsstest du nicht auch berücksichtigen, daß neue Termine in die Datenbanke eingetragen werden? Kann das passieren. Wenn ja, dann müsstest du sowiso die Datenbank sekündlich abfragen.

Das muss ich natürlich auch beachten. Neue Termine können jede Zeit neu angelegt werden. Heißt also doch die DB jede Sekundlich abfragen! Oder nach Schreibvorgängen schauen, falls ein Schreibvorgang stattfindet die Termine neu laden.

Wenn du eh sekündlich ne Query raushauen musst, dann kannst du die Ergebnisse ja sogar ganz konkret bis auf die Sekunde genau filtern lassen. In dem Falle brauchst du gar nichts in ein Array oder eine Liste zuwischenspeichern.
Du weißt ja in diesem Falle genau, dass alle zurückgelieferten Einträge genau jetzt in diesem Moment ein Ereignis auslösen müssen. Dazu iterierst du dann einfach über das SQLResult.

Aber macht da die SQlite DB mit? Schafft sie überhaupt in der einen Sekunde die ganze Abfrage und Ausgabe?

AlexII 11. Mai 2015 15:26

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Obwohl... es reicht ja auch ein Mal pro Minute die DB abzufragen, die Sekunden werden beim Termineintrag ignoriert. Also nur 1x pro Minute, und das muss kein Problem sein! :thumb:

Zacherl 11. Mai 2015 15:28

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von AlexII (Beitrag 1301062)
Zitat:

Zitat von Zacherl (Beitrag 1301061)
Zitat:

Zitat von AlexII (Beitrag 1301058)
Zitat:

Zitat von bernau (Beitrag 1301054)
Müsstest du nicht auch berücksichtigen, daß neue Termine in die Datenbanke eingetragen werden? Kann das passieren. Wenn ja, dann müsstest du sowiso die Datenbank sekündlich abfragen.

Das muss ich natürlich auch beachten. Neue Termine können jede Zeit neu angelegt werden. Heißt also doch die DB jede Sekundlich abfragen! Oder nach Schreibvorgängen schauen, falls ein Schreibvorgang stattfindet die Termine neu laden.

Wenn du eh sekündlich ne Query raushauen musst, dann kannst du die Ergebnisse ja sogar ganz konkret bis auf die Sekunde genau filtern lassen. In dem Falle brauchst du gar nichts in ein Array oder eine Liste zuwischenspeichern.
Du weißt ja in diesem Falle genau, dass alle zurückgelieferten Einträge genau jetzt in diesem Moment ein Ereignis auslösen müssen. Dazu iterierst du dann einfach über das SQLResult.

Aber macht da die SQlite DB mit? Schafft sie überhaupt in der einen Sekunde die ganze Abfrage und Ausgabe?

Das WHERE Statement gibt es auch bei SQLite und wenn du einen entsprechenden Index setzt, wird die Abfrage auch in ordentlicher Zeit durchlaufen. Kommt halt auf die Größe der Datenbank an.
Müsstest du dir auch überlegen, ob es sinnvoll ist die vergangenen Termine wieder aus der Datenbank zu löschen.

AlexII 11. Mai 2015 15:32

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Zacherl (Beitrag 1301065)
... und wenn du einen entsprechenden Index setzt, wird die Abfrage auch in ordentlicher Zeit durchlaufen.

Was meinst Du mit dem Index?

Popov 11. Mai 2015 15:32

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
@AlexII

Hatte ähnliche Aufgabe auch mal, daher kann ich dir sagen: wer beizeiten richtig sortiert, hat später weniger zu suchen. Oder anders ausgedrückt, es ist einfacher (schneller) wenn du die Termine zuerst sortierst und dann suchst, als eine unsortierte Liste jedes Mal komplett durchzusuchen. Ist eine Liste Sortiert, kannst du dir eine Adresse merken, die alte und zukünftige Termine trennt. Das nächste Mal kannst du mit der Suche ab dieser Adresse anfangen. Natürlich mit der Suche aufhören wenn der Termin in der Zukunft liegt. Letztendlich bleiben dir nur eine Handvoll Daten die du durchsuchen musst.

Also, besser zuerst sortieren als später suchen.

Was die TStringList angeht, kann es sein, dass die Frage lautet: was ist schneller, Array mit TDateTime oder StringList mit einer Datumzeit als String? Da möchte ich dir TObjectList ans Herz legen. Muss man zwar eine kleine Klasse basteln, aber dafür bringt sie paar Vorteile.

p80286 11. Mai 2015 15:58

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Index: jede Datenbank sollte einen Index auf das/die Felde(r) haben in denen gesucht wird.

Die Abfrage nach den sekundengenauen Terminen, könnte etwas eng werden, da der Komunikationsoverhead etwas groß wird. Daher vllt. alle 10 sec die Daten der nächsten 10 sec holen. Hat natürlich den Nachteil, daß Termine, die zum Abfragezeitpunkt<Eintragungszeitpunkt<Abfragezeitp unkt+10sec eingetragen werden "verschwinden". Darum solltest Du vllt. erst einmal den Worst case deiner Anwendung definieren, und dann zusehen, das Du diesen beherrschst.

Gruß
K-H

P.S.
Ob Tlist,TObjectlist oder Array, diese Diskussion halte ich jetzt eigentlich für zweitrangig.

jobo 11. Mai 2015 16:46

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von p80286 (Beitrag 1301072)
Darum solltest Du vllt. erst einmal den Worst case deiner Anwendung definieren, und dann zusehen, das Du diesen beherrschst.

Korrekt! Als kleine Ergänzung:
Du brauchst außerdeme ein minimale Reaktionszeit t für die Routine, um deinen Worstcase von tausenden Weckzeiten abzufackeln.
Und Du brauchst eine Entscheidung, was mit timed out Weckzeiten geschieht. Fallen die weg oder baust Du eigentlich eher ne Queue?
Also ich persönlich wäre meinem Wecker nicht böse, wenn er mich ein paar millisekunden zu spät, statt gar nicht weckt.

Apropos Worstcase, tausende Termine, sqlite:
Du bist einer von diesen wichtigen Nerds, die sich bzw. ihren Tagesablauf optimieren und dafür eine Smartphone App (Apple/Android) entwicklen?!
;)

P.S: Weiß nicht ob sqLite das kann, aber es gibt Primärschlüsselverfahren, die direkt beim Einfügen nativ sortieren (Wahrscheinlich braucht man dann für identische Weckzeiten noch ein weiteres Schlüsselattribut (Sequenz)).

Perlsau 11. Mai 2015 17:07

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von AlexII (Beitrag 1301039)
Ok... also es ist folgendes, es geht um einen Wecker. Dieser soll nach mehreren (Hunderte, oder Tausende) Terminen "Ausschau" halten, und bei angegebener Zeit Alarm schlagen. Das heißt, dass ich jede Sekunde die aktuelle Uhrzeit mit der in der DB vergleichen muss. Nun suche ich wie ich das am besten mache. Eine binäre Suche wäre schon sinnvoll, oder?

In meiner Terminverwaltung mache ich das so, daß ich im Datenmodul eine Public-Methode bereitstelle. Beim Programmstart wird der nächste Termin in einer Variablen gespeichert:
Delphi-Quellcode:
Function DatMod.GetNextAlarmDate : TDateTime;
Begin
  Query.Active := False;
  Query.SQL.Clear;
  Query.SQL.Append('select TERMINDATUM, ALARM from TERMINE');
  Query.SQL.Append('where ALARM = 1'); // Boolsche Variablen werden z.B. in Firebird als 0 und 1 gespeichert
  Query.SQL.Append('order by TERMINDATUM'); // das "kleiste" Datum steht am Anfang
  Query.Open;
  Query.Last; // an das "größte" Datum springen
  Result := Query.FieldByName('TERMINDATUM').AsDateTime;
  Query.Active := False;
  Query.SQL.Clear;
End;
Dieses Resultat speichere ich nun in einer Variablen, die in der Ereignisbehandlung vom Timer mit der aktuellen Uhrzeit verglichen wird. Ist das Datum erreicht, klingelts und in der Alarm-Methode wird dann wieder der nächste Termin in diese Variable gesetzt. Empfehlenswert ist auch eine Spalte, die angibt, wieviele Sekunden oder Minuten vor dem eigentlichen Termin der Alarm losgehen soll oder auch eine Variable, die diese Zeit für alle Termine gleich behandelt.

Dejan Vu 11. Mai 2015 20:50

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Also ich würde ja einfach für jeden Wecker den Zeitpunkt des nächsten Bimmelns in eine sortierte Liste eintragen.
Jede Sekunde schaue ich im ersten Eintrag nach, ob es denn Zeit ist. Wenn ja: Bimmele ich und füge für diesen Wecker den Zeitpunkt des nächsten Bimmelns wieder in die Liste an der richtigen Position ein.

So muss ich nie suchen, sondern nur nach dem Bimmeln einmalig per Binärsuche die richtige Stelle finden.

Alternativ nehme ich einfach eine Priority Queue.

Namenloser 11. Mai 2015 20:57

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von jobo (Beitrag 1301088)
P.S: Weiß nicht ob sqLite das kann, aber es gibt Primärschlüsselverfahren, die direkt beim Einfügen nativ sortieren

Das sollte eigentlich jede Datenbank so machen, wenn ein Index auf der Spalte liegt. Der normale Standard-Index ist bei gängigen Datenbanken immer ein balancierter Baum, wenn man nichts anderes spezifiziert. Deswegen kostet das Sortieren bei einer Abfrage auch keine extra Zeit, wenn auf dem Sortierkriterium ein Index liegt.

Du kannst also ruhigen Gewissens jede Sekunde eine Abfrage à la
Delphi-Quellcode:
SELECT * FROM termine WHERE t1 <= zeit <= t2 ORDER BY zeit
machen. Das bleibt auch dann noch fast gleich schnell (O(log n)), wenn die Datenbank sehr groß wird (wobei es natürlich auch noch davon abhängt, wie viele Datensätze zwischen t1 und t2 liegen, logisch).

Dejan Vu 11. Mai 2015 21:22

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
[QUOTE=Namenloser;1301129]
Zitat:

Zitat von jobo (Beitrag 1301088)
Der normale Standard-Index ist bei gängigen Datenbanken immer ein balancierter Baum, wenn man nichts anderes spezifiziert.

Ein B-Baum ist aber kein 'balancierter Baum' (na ja, irgendwie schon). sondern ein Bayer-Baum.
Zitat:

Zitat von Namenloser (Beitrag 1301129)
Delphi-Quellcode:
... WHERE t1 <= zeit <= t2
...

Geht das mit SQLite? Ich würde
Delphi-Quellcode:
zeit BETWEEN t1 and t2
nehmen.
Zitat:

Zitat von Namenloser (Beitrag 1301129)
...fast gleich schnell (O(log n))

Die Basis des Logarithmus ist aber sehr groß: PageSize div SizeOf(Key). Das geht gegen O(1).

Kleine Klugscheißerei am Rande :mrgreen:

Namenloser 11. Mai 2015 21:36

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Dejan Vu (Beitrag 1301136)
Zitat:

Zitat von Namenloser (Beitrag 1301129)
Der normale Standard-Index ist bei gängigen Datenbanken immer ein balancierter Baum, wenn man nichts anderes spezifiziert.

Ein B-Baum ist aber kein 'balancierter Baum' (na ja, irgendwie schon).

Natürlich ist der balanciert? :gruebel: Erfüllt genau die Definition von Wikipedia: „Ein balancierter Baum (englisch oft self-balancing tree) ist in der Informatik ein Spezialfall der Datenstruktur Baum, der eine maximale Höhe von c⋅log(n) garantiert, wobei n die Anzahl der Elemente im Baum angibt und c eine von n unabhängige Konstante ist.“
Außerdem muss es ja nicht zwangsläufig ein B-Baum sein. Ich weiß nicht, was da in der Praxis zum Einsatz kommt. Auch wenn es gut sein kann, dass es tatsächlich ein B-Baum ist. Auf jeden Fall ist es aber ein balancierter Baum.
Zitat:

Zitat von Dejan Vu (Beitrag 1301136)
Geht das mit SQLite? Ich würde
Delphi-Quellcode:
zeit BETWEEN t1 and t2
nehmen.

Keine Ahnung, ich mach nur alle paar Jahre mal was mit SQL.
Zitat:

Zitat von Dejan Vu (Beitrag 1301136)
Zitat:

Zitat von Namenloser (Beitrag 1301129)
...fast gleich schnell (O(log n))

Die Basis des Logarithmus ist aber sehr groß: PageSize div SizeOf(Key). Das geht gegen O(1).

Ja, „fast gleich schnell“ in der Praxis.

BUG 11. Mai 2015 22:50

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Namenloser (Beitrag 1301138)
Außerdem muss es ja nicht zwangsläufig ein B-Baum sein. Ich weiß nicht, was da in der Praxis zum Einsatz kommt.

Ich würde wetten das es eine Variante des B+ Baums ist ... Datenbankers Liebling :lol:

...

Ich hab nachgeschaut: B+ Tree für Daten und B Trees für Indices.

Dejan Vu 12. Mai 2015 06:43

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
@Namenloser: Ich schrieb ja, das ein Bayer-Baum auch balanciert ist, nur ist ein 'B'-Baum kein b-alancierter Baum sondern ein B-ayer-Baum und 'fast gleich schnell' wird bei einigen RDBMS zum 'gleich schnell', wegen der Implementierung des Indexes als B+-Baum. Ich habe ja keine Aussage von Dir negiert sondern nur präzisiert.

AlexII 12. Mai 2015 08:11

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Zitat:

Zitat von Perlsau (Beitrag 1301093)
Zitat:

Zitat von AlexII (Beitrag 1301039)
Ok... also es ist folgendes, es geht um einen Wecker. Dieser soll nach mehreren (Hunderte, oder Tausende) Terminen "Ausschau" halten, und bei angegebener Zeit Alarm schlagen. Das heißt, dass ich jede Sekunde die aktuelle Uhrzeit mit der in der DB vergleichen muss. Nun suche ich wie ich das am besten mache. Eine binäre Suche wäre schon sinnvoll, oder?

In meiner Terminverwaltung mache ich das so, daß ich im Datenmodul eine Public-Methode bereitstelle. Beim Programmstart wird der nächste Termin in einer Variablen gespeichert:
Delphi-Quellcode:
Function DatMod.GetNextAlarmDate : TDateTime;
Begin
  Query.Active := False;
  Query.SQL.Clear;
  Query.SQL.Append('select TERMINDATUM, ALARM from TERMINE');
  Query.SQL.Append('where ALARM = 1'); // Boolsche Variablen werden z.B. in Firebird als 0 und 1 gespeichert
  Query.SQL.Append('order by TERMINDATUM'); // das "kleiste" Datum steht am Anfang
  Query.Open;
  Query.Last; // an das "größte" Datum springen
  Result := Query.FieldByName('TERMINDATUM').AsDateTime;
  Query.Active := False;
  Query.SQL.Clear;
End;
Dieses Resultat speichere ich nun in einer Variablen, die in der Ereignisbehandlung vom Timer mit der aktuellen Uhrzeit verglichen wird. Ist das Datum erreicht, klingelts und in der Alarm-Methode wird dann wieder der nächste Termin in diese Variable gesetzt. Empfehlenswert ist auch eine Spalte, die angibt, wieviele Sekunden oder Minuten vor dem eigentlichen Termin der Alarm losgehen soll oder auch eine Variable, die diese Zeit für alle Termine gleich behandelt.

Cool, danke für das Beispiel... ich schaue es mir an. :thumb:

Dejan Vu 12. Mai 2015 12:41

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Das sollte auch so gehen
Code:
select min (TERMINDATUM) from Termine where Alarm=1
oder
Code:
select first 1 TERMINDATUM from Termine where Alarm=1 order by TERMINDATUM
Vorteil: Beide liefern nur einen Datensatz zurück, anstatt alle.
Die erste Variante ist eigentlich so, "wie man es macht".

Aber wenn Du alle Termine eh benötigst, ist natürlich Perlsau's Variante vorzuziehen (bis auf die letzten Zeilen natürlich),

Mavarik 12. Mai 2015 16:02

AW: Wo binäre Suche schneller, mit Array oder StringList?
 
Code:
Select ID FROM Termine order by ID,DESC LIMIT 1;
Delphi-Quellcode:
if ID > LastID then
Code:
Select ID,AlarmTime FROM Termine Where (ALARM=1) and (AlarmTime > "+FormatDateTime('yyyy-mm-dd hh:nn:ss',[NOW]+'")' order by AlarmTime,ASC LIMIT 10;
hmm


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:22 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