Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   while not Eof(myFile), wie CPU Load in den Griff bekommen? (https://www.delphipraxis.net/163257-while-not-eof-myfile-wie-cpu-load-den-griff-bekommen.html)

schwa226 21. Sep 2011 22:32

while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Hallo!

Ich habe einfach keine Idee wie ich es schaffe die CPU Load in den Griff zu bekommen!

Ich öffne ein TXT File und lese eine Zeile nach der anderen ein.
Wenn die ersten 4 Chars dem gesuchten entsprechen habe ich die richtige Zeile gefunden und die Schleife wird abgebrochen.

Delphi-Quellcode:
while not Eof(myFile) do
begin
ReadLn(myFile, tmp_line);
...
..
end;
In dieser Schleife geht die CPU Last natürlich hoch. Ein Sleep(1) würde die CPU Last lösen, aber die Dauer natürlich extrem verlängern wenn es ca. 10000 Zeilen sind.

Wie macht man das am besten um trotzdem schnell zu sein aber die CPU Last unten zu halten?

Danke!

Sir Rufo 21. Sep 2011 22:39

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
1. Lade die Datei in eine StringList und Suche in selbiger
2. lagere den Suchcode in einem Thread aus

Die CPU Last ist eigentlich nicht schlimm (wenn der Rechner arbeitet ist es ja gut)
Schlecht ist nur, wenn die Form lange blockiert wird, dann sieht es so aus, als ob das Programm abgestürzt ist ;)

Edlmann 21. Sep 2011 22:41

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Naja, das durchgehen der Zeilen benötigt einfach die CPU-Rechenzeit. Und um das möglichst schnell hinzubekommen, steigt somit die CPU-Last auf 100% (bzw die Last von einem Kern). Wenn du nicht willst dass deine Anwendung solange einfriert, könntest du das ganze in einen Thread auslagern, oder mittels Application.ProcessMessages weiterhin die Oberfläche aktiv halten. Oder möchtest du das dem Rest deiner Anwendung die CPU-Last zur Verfügung steht, und deswegen die Schleife ausbremsen? Auch dann wäre ein Thread die richtige Lösung.

Edit: Goddemit, nicht schnell genug.

Luckie 21. Sep 2011 23:05

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Was ist dir lieber? Dass die CPU das tut für was du sie gekauft hast und arbeitet oder, dass sie zwischen durch Däumchen dreht? Was ist daran so schlimm, wenn die CPU ausgelastet ist? Kritisch wird es erst, wenn sie anderen Prozessen keine Ressourcen mehr zur Verfügung stellt. Aber das passiert nur wenn man dem Thread die höchste Prioritätsstufe gibt, was du wahrscheinlich nicht gemacht hast.

FredlFesl 22. Sep 2011 04:40

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
10000 Zeilen sind kein Problem, das merkt man doch gar nicht... Wenn man, wie schon erwähnt, z.B. mit einer TStringlist arbeitet.

jaenicke 22. Sep 2011 05:07

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Oder du nimmst diese Unit von mir dafür. Diese bietet ein Readln an, so dass du nicht viel umstellen musst, ist durch die Verwendung einer MMF aber deutlich schneller. ;-)
http://www.delphipraxis.net/151898-s...ei-reader.html

schwa226 22. Sep 2011 06:57

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Danke für eure Tipps!

Meine Programm ist eine Multithread Anwendung.
Und wenn nun ein Thread für eine Kurze Zeit die CPU voll auslastet haben die anderen ja nichts mehr davon. Und wenn nun mehrere Threads gleichzeitig das File lesen wollen geht die CPU Last erst richtig hoch.

Ich werde es einmal mit der TSJMmfFileReader probieren.
Das Problem was ich noch habe, ist das ich gleichzeitig auch eine SQLite Database genau so durchsuchen will.

Meine Idee ansonsten ist die Dateien global einzulesen. Bei einer Suche wird zuerst überprüft ob sich die Datei verändert hat (Durch externen Editor). Wenn nicht dann die Globale (z.B. StringList) verwenden oder ansonsten halt die Datei neu laden. Um die Daten aber neu zu laden bräuchte man wieder eine ThreadSafe StringList was wieder den gleichzeitigen Zugriff blockiert.

Wie gesagt, die Daten werden nur gelesen und nicht verändert. Somit sollte eine globale StringList ausreichen.

Sir Rufo 22. Sep 2011 08:16

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Also mal zusammengefasst:

Du hast da eine Text-Datei mit mehreren Zeilen.
Die Zeilen unterscheiden sich auf jeden Fall in den ersten 4 Zeichen.
Nach diesen 4 Zeichen möchtest du suchen um dann den Rest der Zeile zu finden.

Dann würde es sich doch anbieten diese Datei zu lesen und einen sortierten Index über die ersten 4 Zeichen zu generieren.
in diesem Index wird dann gesucht (das geht z.B. in einer sortierten StringList rasend schnell)

Alle Threads greifen auf diesen Index zu ... oder kopieren sich den Index in eine neue Instanz und suchen dann.

Wenn aber viele Threads die gleiche Datei immer wieder durchsuchen, dann ist der Rechner die meiste Zeit damit beschäftigt die Daten von der Platte zu lesen und das treibt die CPU Last unnötig nach oben.

Luckie 22. Sep 2011 09:13

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von schwa226 (Beitrag 1125937)
Und wenn nun ein Thread für eine Kurze Zeit die CPU voll auslastet haben die anderen ja nichts mehr davon.

Wenn du die Threads nicht auf mehrere Kerne verteilst, kann auch die CPU nur eins nach dem anderen machen und da spielt die Auslastung keine Rolle.

Zitat:

Und wenn nun mehrere Threads gleichzeitig das File lesen wollen geht die CPU Last erst richtig hoch.
Das ist Unsinn, was du da machst. Mit mehreren Threads aus einer Datei zu lesen bringt keinen Geschwindigkeitsvorteil, weil die Festplatte auch immer nur von einer Stelle lesen und so nur einen Thread jeweils bedienen kann.

Und noch mal, was hast du gegen eine hohe CPU-Auslastung? Wenn die CPU dein Programm ausführen soll, dann muss sie eben arbeiten. Dass andere Programme keine so hohe CPU-Auslastung haben liegt schlicht und ergreifend daran, dass sie zu 99% der Laufzeit nichts tun.

Du scheinst noch nicht zu wissen wie Windows sein Multitasking verwaltet. Lesetipp: http://michael-puff.de/Programmierung/Delphi/Tutorials/

jaenicke 22. Sep 2011 10:05

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von Luckie (Beitrag 1125960)
Das ist Unsinn, was du da machst. Mit mehreren Threads aus einer Datei zu lesen bringt keinen Geschwindigkeitsvorteil, weil die Festplatte auch immer nur von einer Stelle lesen und so nur einen Thread jeweils bedienen kann.

Genau das löst das Auslesen per MMF. Und der Reader lässt sich sehr einfach für das Auslesen der jeweils 4 Zeichen modifizieren.

Aber davon abgesehen gibt es vermutlich eine bessere algorithmische Lösung für die Aufgabe. Was passiert denn in den Threads sonst noch? :gruebel:

himitsu 22. Sep 2011 10:10

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
PS: paralelle Zugriffe auf eine Festplatte bremsen sich gegenseitig aus.

Die Leseköpfe sind langsam
- also sequentielles Arbeiten ist da besser (solange zwischendurch nicht mindestens genausolange gerechnet, wie auf dem Datenträger drauf rumgemacht wird)

Luckie 22. Sep 2011 10:37

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von himitsu (Beitrag 1125968)
PS: paralelle Zugriffe auf eine Festplatte bremsen sich gegenseitig aus.

Ich dachte, das hätte ich bereits erwähnt? :gruebel:

jaenicke 22. Sep 2011 16:32

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Und ich habe gerade auch schon erwähnt, dass genau das durch die MMF minimiert wird. Wir drehen uns im Kreis. Hilfe, eine Zeitschleife. :mrgreen:

p80286 22. Sep 2011 17:35

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von schwa226 (Beitrag 1125937)
Das Problem was ich noch habe, ist das ich gleichzeitig auch eine SQLite Database genau so durchsuchen will.

Meine Idee ansonsten ist die Dateien global einzulesen. Bei einer Suche wird zuerst überprüft ob sich die Datei verändert hat (Durch externen Editor). Wenn nicht dann die Globale (z.B. StringList) verwenden oder ansonsten halt die Datei neu laden. Um die Daten aber neu zu laden bräuchte man wieder eine ThreadSafe StringList was wieder den gleichzeitigen Zugriff blockiert.

Mir scheint, daß nicht der zugriff auf die Festplatte das Problem ist, sondern daß hier einige Abläufe nicht richtig zueinander passen.

Gruß
K-H

FredlFesl 22. Sep 2011 17:40

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von jaenicke (Beitrag 1126056)
Und ich habe gerade auch schon erwähnt, dass genau das durch die MMF minimiert wird. ...

Komisch, das (MMF superschnell ist) konnte ich bisher noch nicht feststellen. Vielleicht habe ich eine falsche Klasse.. Wäre das ein Thema für einen separaten Thread, oder hast Du zufällig schon was vorbereitet? ;-)

jaenicke 22. Sep 2011 21:17

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
In dem verlinkten Thread findest du eine Demo. Von SSD habe ich damit Geschwindigkeiten von 300 MiB/s beim zeichenweisen (!) Auslesen. ;-)

schwa226 23. Sep 2011 09:21

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zur Erklärung:
Jeder Thread hat einen TCP Client. Dieser empfängt über ein Kommando eine Hex-ID.
Mit dieser ID sucht sich nun der Thread aus dem Textfile den dazu passenden String.
Danach startet die eigentliche Abarbeitung der empfangenen Daten.

Um die Textdatei ändern zu können ohne die Anwendung neu starten zu müssen habe ich das File bei jeder Abfrage neu geöffnet und nach der Suche wieder geschlossen.

Wenn ich die Datei einmal öffne und global zur Verfügung stelle werden ja externe Änderungen der Textdatei nicht berücksichtigt. Dann müsste man immer wieder einmal überprüfen ob sich die Datei verändert hat (vielleicht wieder ein eigener Thread).
Um die globale geöffnete Datei zur Laufzeit zu verändern/upzudaten würde dann aber auch eine Threadsichere TStringList benötigt. Oder man started halt die Anwendung neu, was zu einer Unterbrechnung der Verbindung führen würde.

QuickAndDirty 23. Sep 2011 10:13

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Las mich raten, die Datei ist eine filebasierte Datenbank Datei und du möchtest die Datenbank umgehen?
Vielleicht um die beknackten Windows Freigaben nicht machen zu müssen?

Ich glaube nicht das du das sooo hinbekommst.

jaenicke 23. Sep 2011 12:33

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Das macht auch gar keinen Sinn das zu versuchen.

Genau für das was du beschreibst gibt es Datenbanken...

p80286 23. Sep 2011 13:04

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Wenn ich das jetzt richtig verstanden habe, gibt es maximal $FFFF Strings, die sollten eigentlich problemlos in einer Stringlist verwaltbar sein. Mit sorted=true Und einer Bin.Suche sollte das Suchen so schnell gehen, daß für das Einfügen/Überschreiben neuer Daten genug Zeit bleibt, da könnte man wahrscheinlich noch öfters mal eine Sicherung fortschreiben.

(ein Feuervögelchen realisiert das bestimmt einfacher, aber für echte Männer gilt: für solche Kleinigkeiten brauch ich doch keine DB)

Gruß
K-H

schwa226 26. Sep 2011 19:44

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Ich habe mich jetzt etwas damit gespielt.

Es macht keinen Unterschied ob die Datei global geöffnet wird oder bei jedem Suchen neu geöffnet wird.
Bis halt auf das, dass mehr Festplattenaktivität herscht.

Alleine die StringList durchsuchen macht die CPU Last.
Ich habe jetzt die Suche verbessert und bin von ~10% Last auch <=5% gekommen.
Also eine Verbesserung von ca 50%.

Mal sehen ob ich das mit der binären Suche noch etwas verbessern kann.

jaenicke 27. Sep 2011 05:29

AW: while not Eof(myFile), wie CPU Load in den Griff bekommen?
 
Zitat:

Zitat von schwa226 (Beitrag 1126809)
Alleine die StringList durchsuchen macht die CPU Last.
Ich habe jetzt die Suche verbessert und bin von ~10% Last auch <=5% gekommen.
Also eine Verbesserung von ca 50%.

Warum ist es eine Verbesserung, wenn sich die CPU langweilt? Das heißt doch nur, dass andere Faktoren den Vorgang ausbremsen.

Wenn es dir ausschließlich um die CPU-Last geht, kannst du auch zwischen jeden Zugriff ein Sleep machen, dann dauert es noch länger, aber dafür ist die CPU-Last bei 0%. Aber was bringt das?

Eine schnellere Suche wäre z.B. über ein einmaliges Einlesen als Zahl oder Hash möglich. Zum Beispiel über TDictionary oder THashedStringList.


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