AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Container?
Thema durchsuchen
Ansicht
Themen-Optionen

OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Container?

Ein Thema von juergen · begonnen am 15. Okt 2017 · letzter Beitrag vom 27. Okt 2017
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#1

OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Container?

  Alt 15. Okt 2017, 19:51
Hallo zusammen,

ich habe ein Programm was Lied-Dateien einliest. Das Programm funktioniert. Aber inzwischen ist mir die Wartezeit beim Einlesen der Dateieigenschaften einfach zu lang. Am Anfang habe ich mich nach reiflicher Überlegung bewusst *gegen* eine Datenbank entschieden! Somit war klar, dass ich beim Starten des Programms die Dateien immer neu einlesen muss.
Das einlesen der Dateien über FindFirst() dauert bei ca. 15.000 Dateien akzeptable 1,7xxx Sekunden (mit Einfügen in ein Grid).
Allerdings dauert das Auslesen der Dateieigenschaften wie z.B. der MP3-Tags weitere 1:50 Minuten. An dem Auslesen der Dateieigenschaften kann ich nichts mehr optimieren.
Nun war meine Überlegung das Einlesen der Dateieigenschaften zu parallelisieren. Da ich noch Delphi XE nutze bin ich auf die OmniThreadLibrary gestoßen.

Nun meine Fragen (als absoluter Neuling in diesem Bereich):
1. Welche Funktionsart aus OmniThreadLibrary wäre für meine Anforderung richtig? So wie ich es verstanden habe könnte es Pipelines sein, bin mir aber nicht sicher.
2. Welchen (Threadsaved) Container soll ich für das Zwischenspeichern der Dateieigenschaften verwenden? Meine momentane Vorstellung ist, dass ich die Dateieigenschaften temporär in ein Container (ObjectList?) einlese.
3. Nach dem parallelen einlesen der Dateieigenschaften plane ich den Inhalt des "Containers" an ein Grid (cxGridTableView von DevExpress) weiterzugeben. Sind diese Überlegungen richtig/sinnvoll?

Ich danke schon mal im Voraus für eure Hilfe, Anregungen und Schubse in die richtige Richtung!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.400 Beiträge
 
Delphi 12 Athens
 
#2

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 15. Okt 2017, 22:51
Die Anzahl der Dateien ist fast irrelevant, schlimmer ist die Anzahl der Verzeichnisse, welche so gelesen wird. (also in Bezug auf die Dateisuche > FindFirst/FindNext)
Und dann nervt erst die Anzahl der Dateien, aber da du dort ja eigentlich kein großes Problem hast ...
Aber multithread kannst du beim Zugriff auf dein VCL-Grid vergessen.

Multithread auf einer HDD suchen verbessert auch nicht immer alles ... parallele Zugriffe können schnell mal alles extrem ausbremsen. (bei SSD sieht es anders aus)


Nicht alle Daten im Grid anzeigen/laden, sondern nur intern speichern, in einer Liste oder Tree,
oder ein schnelleres Grid verwenden (VirtualStringTree).



Du kannst auch weiterhin beim Start suchen und zur Laufzeit eine DB oder ein MemoryDataSet mit den Daten füllen und in einem DB-Grid anzeigen.
Delphi-Referenz durchsuchenTDataSet.Filter oder richtige SQL-Abfragen auf eine MemoryDB oder über LocalSQL von FireDAC ... da kannst du dann schöner in deinen Daten suchen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (15. Okt 2017 um 22:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.284 Beiträge
 
Delphi 12 Athens
 
#3

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 16. Okt 2017, 13:40
Oder, etwas verrücktere Idee: Zur Visualisierung statt eines Grids einen VirtualTreeView verwenden und nur die Detaildaten der Dateien auslesen, die sich tatsächlich im Viewport befinden. Ob ein solches Vorgehen möglich ist, hängt natürlich stark von der jeweiligen Anwendung ab.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 16. Okt 2017, 18:47
Hallo,

mir ging es wirklich ums parallelisieren beim Einlesen der Dateieigenschaften. Das Grid ist in 1-2 Sek. mit allen Daten gefüllt. Nur beim parallelisieren des Ausleseprozesses der Dateieigenschaften sehe ich eine Möglichkeit die Wartezeit *spürbar* zu verringern. Doch worin sollte ich die Dateieigenschaften zwischenspeichern um diese nach dem parallelen Einlesen dem Grid zuzuordnen? Sollte ich ein Record verwenden, eine Klasse oder Objectlist oder eine generische Liste oder was gibt's noch? Das Ganze müsste halt Threadsaved sein.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.284 Beiträge
 
Delphi 12 Athens
 
#5

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 17. Okt 2017, 07:16
Das Grid ist in 1-2 Sek. mit allen Daten gefüllt.
Darum ging es mir eigentlich gar nicht. Vielmehr als Denkanstoß, ob du die zig Tausend Dateien NUR einliest um sie AUSSCHLIESSLICH zu visualisieren. Oder tust du noch andere Dinge mit dem erhobenen Datenbestand? Falls es dir nur um Visualisierung geht, was ich aus der Aussage ableite dass du keine Datenbank verwenden willst, dann könntest du mit dem Virtualtree eine Menge Rechenzeit einsparen und ggf. ganz auf Multithreading verzichten.

Das Ganze müsste halt Threadsaved sein.
Wenn ich den Ablauf richtig verstanden habe, dann kennst du die genaue Anzahl von einzulesenden Dateien ja schon vorher. In dem Fall kannst du dir doch eine entsprechende Anzahl Records erstellen, welche die einzulesenden Daten aufnehmen, diese in eine TList packen und dem jeweiligen Thread nur einen Pointer auf den jeweiligen Record mitgeben. Synchronisieren müsstest du nur die Teile, die während des Einlesens schon benötigt werden. Der Rest liegt einfach erstmal als reservierter Speicher vor und wird nach und nach gefüllt.

Beim Datei-Explorer sieht man das sehr schön. Wenn man einen Ordner mit vielen Bildern hat und den Explorer auf Miniansichten stellt. Dann sieht man zunächst erstmal nur das Datei-Icon (anhand der Metadaten ausgewählt) und nachdem der Reader-Thread drüber marschiert ist, wird die Darstellung im Listview aktualisiert mit einem gerenderten Thumbnail (was wohl noch vom Reader-Thread erledigt wurde).
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 17. Okt 2017, 22:26
@Codehunter ,
erst mal Danke für deine Tipps.
Ums visualisieren geht's mir gar nicht. Letztendlich geht es ums suchen von Interpreten, Titeln usw. um sich aus der gefilterten Menge schnell Playlisten zu erstellen.
Dazu muss ich eben alle Dateinamen, Dateipfade und Dateidatum einlesen. Das läuft schon über einen Thread und ist nicht das Problem.
Das Einlesen der Metadaten dauert dann aber zu lange. Diesen Prozess möchte ich beschleunigen durch Parallelisierung.
Nur wohin lese ich die Metadaten ein? Du nanntest hier eine TList. Wenn ich z.B. Interpret, Titel, Album, Bewertung Lyrics, Kommentar, Track#, Disk#, Dateidatum usw. pro Datei habe, sehe ich das Problem der Datentrennung. Wie soll ich die Metadaten einer Datei in einer TList speichern? Semikolon-getrennt? Dann ist das Einlesen der Daten in das Grid aufwendig. Schön wäre eigentlich eine InMemory-Table wie z.B. ClientDataSet oder dxMemTable von DevExpress. Die sind aber leider nicht Thread safe. Ein Record wäre auch eine Idee. Da finde ich aber nichts in meiner Delphi Hilfe ob der Thread safed ist.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
561 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 13:29
Ohne die MP3Tags sprich einen Index darüber in einer Datei (DB) zu speichern wird die Sache nicht schnell. Eine relationale Desktop DB egal welcher Ausprägung wir zu langsam für einen Musikplayer.

Wenn du irgendwelche Datenbestände anhängst, dann muss man den Index sowieso immer neu aufbauen. In der Praxis baut der MP3 sammelnde Menschen nicht selbst ein Archiv auf, sondern irgendwer gibt ihm ein 'Medium'.

Du brauchst im Mittel zu lange für die Suche und das Laden. Unserer Erfahrung nach machen Benutzer nicht lange dabei mit, wenn sie ein Buchstaben tippen und es rührt sich nichts .

Spätestens beim Suchen nach Titeln oder Teilen von Titeln bist du weg von der Schüssel.

Bei 'unserem' (nicht meinem im Sinne von meinem Eigentum) Musikplayer kam das Repertoire gleich mit mit manuell eingestellten Fadepunkten usw... Damit hat sich die Frage bezüglich dieses Repertoires nicht gestellt, aber beim Import und der Verwaltung für eine Enduser Version ohne Content.

Ich habe damals Indizes pro Directory gemacht und die konnte ich mergen zur Laufzeit.

Metadaten zu allen Lieder in einer ObjectList zu halten ist vermutlich etwas übertreiben.

15k Dateien ist für ein Musikarchiv eher das untere Limit. Das funktioniert für den Einzelnen, wenn du aber ein allgemeineres Archiv anschaust gehst du über 100k Titel.

Ich hoffe du willst das Programm nicht verkaufen. Den wenigsten ist bewusst, dass selbst wenn man die Lautstärke automatisch halbwegs normiert geht die Klangqualität genauso wie die natürliche Lautstärke verloren.

Zumal ich nicht genau weiß was das Programm macht ... deswegen meine Erläuterung aus der Sicht eines Musikplayers.

Hallo zusammen,
Allerdings dauert das Auslesen der Dateieigenschaften wie z.B. der MP3-Tags weitere 1:50 Minuten. An dem Auslesen der Dateieigenschaften kann ich nichts mehr optimieren.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.284 Beiträge
 
Delphi 12 Athens
 
#8

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 15:07
@MichaelT: Das sehe ich eigentlich ganz genauso. Der TE hat das Thema Datenbank ja von vornherein ausgeschlossen, weshalb ich mich auf eine Antwort zur konkreten Frage beschränkt habe. Prinzipiell ist ein multithreaded Datei-Auslesen ja nicht verkehrt. Was man dann aus den gewonnenen Daten macht, steht ja auf einem anderen Blatt.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.176 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 25. Okt 2017, 20:15
Hallo Codehunter,
hallo MichaelT,

leider habe ich noch keine Zeit gefunden mich mit Threads zu beschäftigen. Ich denke ich benötige dafür viel Zeit.

Zum Thema Datenbank vs. Daten (Musik-Tags) speichern in ein DevExpress-Grid (letztendlich eine Objectlist):
Es gibt einen sehr guten Player mit SQL-Lite-Datenbank -> MediaMonkey. Das ist quasi die eierlegende Wollmichsau in dem Bereich.

Warum hatte ich mich nun gegen eine Datenbank entschieden?
Das Problem sind die Änderungen an den Musikdateien. Auch der geniale MediaMonkey speichert nicht alle Änderungen in der Musikdatei selbst, sondern in seiner DB.
Weiterhin besteht das Problem, wenn man Musikdateien mit anderen Programmen ändert, dass dann *konsistent* zu synchronisieren *ohne jedes Mal die ganzen Dateien neu zu scannen*.
Aus diesem Grunde habe ich mich gegen eine DB entschieden. Ich speichere die Bilder und Tag-Änderungen *direkt* in den Musikdateien und brauch mich nicht um Synchronisierung kümmern.
Die Suche über das Grid ist vernachlässigbar, also schnell genug wie ich finde. Bei ca. 60.000 Dateien benötigt die Suche weniger wie 1 Sekunde.
Weiterer Vorteil OHNE Datenbank: Da alle Änderungen in den Dateien selbst gespeichert werden, ist der Wechsel zu einem anderen Programm unproblematisch.


Ich habe also nur das Problem des Zeitverhaltens beim Einlesen der Musik-Eigenschaften (Tags).


Aber auch hier habe ich mit Testprogrammen inzw. festgestellt, dass Parallelisierung nur zum Teil hilft. Der limitierende Faktor ist wohl die Festplatte! Wenn ich mit 8 Threads die Dateien einlese von einem (langsamen) NAS-Laufwerk ist das langsamer als mit 4 Threads. Bei meiner SSD sieht es besser aus.

OmniThreadLibrary scheint mir zum einarbeiten leichter zu sein, da es dazu ein Buch gibt und etliche Beispiele. Das werde ich aber erst sehen, wenn ich dazu komme mich mit dem Thema zu beschäftigen.
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.284 Beiträge
 
Delphi 12 Athens
 
#10

AW: OmniThreadLibrary: Was ist für meine Anforderung der richtige Weg? Welchen Contai

  Alt 26. Okt 2017, 07:19
Aber auch hier habe ich mit Testprogrammen inzw. festgestellt, dass Parallelisierung nur zum Teil hilft. Der limitierende Faktor ist wohl die Festplatte! Wenn ich mit 8 Threads die Dateien einlese von einem (langsamen) NAS-Laufwerk ist das langsamer als mit 4 Threads. Bei meiner SSD sieht es besser aus.
Nun ja, alles andere hätte mich auch gewundert. Irgendeinen Grund muss es ja geben, dass SSDs so beliebt sind Es gibt immer limitierende Faktoren (Flaschenhälse). Bei einem NAS sind das noch viel mehr als bei einer lokal eingebauten Festplatte. Ich kenne genug Werbeversprechen mit großen Zahlen und wenn man genauer hinschaut ist alles nur heiße Luft. NAS mit GbE-Anbindung ist inzwischen Usus. Doch wie ist die Schnittstelle im System angebunden? Nicht selten findet man da noch 33 MHz PCI-Busse. Oder der verbaute SoC verdient nicht mal die Bezeichnung "CPU". Dann ist auch noch zu klären, ob die Netzwerkverbindung durchgehend Fullduplex läuft oder nicht - WLAN dazwischen: Schon nur noch Halbduplex.

Thumbs.db - schon mal gehört? Microsoft cached Miniaturansichten von Bilddateien auch in einer Datenbank. Aus den selben Gründen. Ich würde einen Cache in so ein Programm einbauen und zusätzlich eine Benutzerfunktion, welche die Daten in zwei Wegen synchronisiert: Vom Cache in die Dateitags oder umgekehrt. Welche Richtung bei Asynchronität bevorzugt werden soll, würde ich dem Anwender überlassen.

Grundsätzlich stellt sich die Frage: Entwickelst du nur für den Hausgebrauch oder marktorientiert?
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:29 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