Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   IdHttp.Get & Geschwindigkeit (https://www.delphipraxis.net/168387-idhttp-get-geschwindigkeit.html)

G-Baumstamm 18. Mai 2012 10:19

Delphi-Version: 7

IdHttp.Get & Geschwindigkeit
 
Heyho liebe Expertengemeinde,

erstmal will ich kurz die Situation beschreiben: Ich hab 10 Namen, zu denen ich von einer Website Informationen auslesen möchte. Wenn ich das manuell ohne Programm mache, muss ich zunächst den Namen auf der Website in die Suche eingeben, kriege dann mehrere Varianten von denen ich mir die richtige aussuche, dann lade ich die Seite und habe meine Infos.

Realisiert habe ich das folgendermaßen: Aus meinem Namen generiere ich die URL der Suchanfrage, lade mit TIdHttp.Get(URL) den Code der Website in einen String, ermittle mittels String-Operationen die ID zu dem Namen, aus dieser ID kann ich dann die URL der Seite mit meinen Infos generieren, den Quelltext dieser wieder mit Get in einen String transferieren und mit String-Operationen meine Informationen auslesen.

Das funktioniert soweit auch problemlos. Allerdings dauert der ganze Vorgang pro Name etwa 10 Sekunden, also läuft das Programm über 1einhalb Minuten auf Hochtouren, so das es auf etwaige Benutzeraktionen überhaupt nicht mehr reagiert. Meine Tests haben ergeben, das etwa 95% der Zeit für das Laden des Quelltexts mit Get draufgehen, an anderen Stellen ist eine Optimierung für mich also im Moment wenig sinnvoll.

Deshalb die Fragen:

1) Kann man mein Vorgehen irgendwie beschleunigen / optimieren ? Also mit nem anderen Ansatz, der das gleiche Ergebnis liefert, oder ner Optimierung von meinem, oder weiß der Geier ...

2) Unabhängig davon, wie lange das Programm beschäftigt ist: Kann ich irgendwie erreichen, das es währenddessen nicht völlig "tot" ist ? Wenn nen Browser ne Website lädt, reagiert er ja auch nicht die ganze Zeit weder auf Klicken auf Schließen / Minimieren / Buttons in der Toolbar etc ...

Vielen Dank für Eure Hilfe !

Luckie 18. Mai 2012 10:49

AW: IdHttp.Get & Geschwindigkeit
 
Da ich mal davon ausgehe, dass die Webseiten nicht sonderlich groß sind, wird es am Server liegen, dass er die Seiten nicht schneller ausliefern kann. Und damit dein Programm noch reagiert währenddessen musst du den Code für das Runterladen in einen Thread auslagern.

G-Baumstamm 18. Mai 2012 11:28

AW: IdHttp.Get & Geschwindigkeit
 
Danke für die Antwort erstmal schonmal ...

zu 1) Wenn ich die Seiten im Firefox aufrufe laden die innerhalb von weniger als ner Sekunde komplett, trotzdem braucht IdHttp.Get 4-5 Sekunden dafür, das muss man doch irgendwie optimieren können ...

zu 2) Klingt nach ner guten Idee, leider hab ich keine Ahnung von Threads ... ;)

Ich hab jetzt ne Klasse von TThread abgeleitet. Vorher hatte ich zum Testen die Berechnung über einen Button gestartet, jetzt habe ich den Code aus dem OnClick unverändert in TProcessThread.Execute geschrieben, und das
Delphi-Quellcode:
  Thread := TProcessThread.Create(true);
  Thread.FreeOnTerminate := True;
  Thread.Resume;
in meinem Button stehen ... leider macht das Programm nach Klicken auf den Button nun einfach garnichts mehr, und es lässt sich auch nix mehr anklicken etc. Was mache ich da falsch ?

Luckie 18. Mai 2012 11:38

AW: IdHttp.Get & Geschwindigkeit
 
Zitat:

Zitat von G-Baumstamm (Beitrag 1167078)
Was mache ich da falsch ?

Ohne den Code für den Thread zu sehen sehr schwierig, da meine Glaskugel gerade in Reparatur ist.

G-Baumstamm 18. Mai 2012 12:38

AW: IdHttp.Get & Geschwindigkeit
 
Sorry, dachte es wäre ein generelles Problem mit dem Thread, da der Code ja immerhin außerhalb des Threads einwandfrei läuft.

Sind aber über 2000 Zeilen Code, in die du dich sicherlich jetzt nicht einarbeiten möchtest, zudem lässt sich auch kein konreter Fehler reproduzieren, sondern es gibt immer unterschiedliche Fehler (Access Violation, Call to an OS-Function Failed, Stillstand ohne Fehlermeldung) an unterschiedlichen Stellen ...

Um das Pferd mal von hinten aufzuzäumen: Gibt es irgendeine Möglichkeit die Events der Form an sich auszulagern ? Also die Berechnungen so laufen zu lassen wie bis jetzt, aber klicken auf Buttons etc in nem extra Thread zu behandeln ? Wäre sicherlich einfacher ...

Daniel 18. Mai 2012 12:53

AW: IdHttp.Get & Geschwindigkeit
 
Eines der Probleme liegt noch woanders und hat mit Threads gar nichts zutun:
Wenn ich Dich richtig verstanden habe, dann bringt Dir Dein FireFox die gewünschte Seite in etwa 1 Sekunde auf den Rechner. Deine Anwendung benötigt derzeit pro Anfrage etwa die fünffache Zeit. Das ist und bleibt ein Problem, welches Du mittels Verwendung von Threads zwar in den Hintergrund rücken, aber nicht lösen kannst.

Folgender Vorschlag: Baue eine Test-Anwendung, die auf einen Button-Klick nur jeweils eine Abfrage startet und versuche, anhand dieses Minimal-Beispiels die benötigte Zeit zu reduzieren. Später kannst Du das dann immer noch ein einen Thread auslagern. Ein TidHTTP.Get() ist wenigstens nicht pauschal um den Faktor 5 langsamer, da muss also irgendwo noch der Wurm drin sein - den Du aber meiner Ansicht leichter entdecken wirst, wenn Du Dich vorerst von Threads fern hältst.

Luckie 18. Mai 2012 13:14

AW: IdHttp.Get & Geschwindigkeit
 
Na ja, ich nehme an im Konstrukt des Threadobjektes erstellst du die IdHTTP Komponente und im Destruktor gibst du sie wieder frei. Entscheidend dürfte hier die Execute Methode sein.

p80286 18. Mai 2012 13:16

AW: IdHttp.Get & Geschwindigkeit
 
Zitat:

Zitat von G-Baumstamm (Beitrag 1167092)
zudem lässt sich auch kein konreter Fehler reproduzieren, sondern es gibt immer unterschiedliche Fehler (Access Violation, Call to an OS-Function Failed, Stillstand ohne Fehlermeldung) an unterschiedlichen Stellen ...

das hört sich an wie der diskrete Aufruf zu einen Debugging-Session.
Eine AccessViolation deutet in den meisten Fällen auf einen Griff ins Leere hin. da wurde etwas freigegeben oder nicht richtig initialisiert auf das das Programm zugreifen will.
"Stillstand ohne Fehlermeldung" ist oft eine Endlosschleife, gerne ist auch ein nicht sichtbarer Dialog der auf eine Eingabe wartet dafür zuständig. In beiden Fällen ist eine Fehlermeldung unwahrscheinlich, da das Programm formal das tut was es soll.

Gruß
K-H

jaenicke 18. Mai 2012 13:26

AW: IdHttp.Get & Geschwindigkeit
 
Zitat:

Zitat von G-Baumstamm (Beitrag 1167092)
Sind aber über 2000 Zeilen Code, in die du dich sicherlich jetzt nicht einarbeiten möchtest, zudem lässt sich auch kein konreter Fehler reproduzieren, sondern es gibt immer unterschiedliche Fehler (Access Violation, Call to an OS-Function Failed, Stillstand ohne Fehlermeldung) an unterschiedlichen Stellen ...

Die Fehler hören sich danach an als ob du auf schon nicht mehr existierende Objekte zugreifst (z.B. auf das Threadobjekt nach dessen Freigabe) oder aus dem Thread heraus unsynchronisiert auf Daten außerhalb des Threads.

Viel Quelltext wäre immer noch besser als gar keiner und da muss man sich auch nicht einarbeiten, sondern es vermutlich nur mal überfliegen. Aber davon abgesehen wirst du doch wohl die relevanten Stellen daraus entnehmen können, oder? Also sprich Erzeugung des Threads, Code im Thread zum Herunterladen an sich, ...
Die Verarbeitung nach dem Herunterladen wäre z.B. uninteressant, wenn die Verzögerung schon vorher auftritt.

Zitat:

Zitat von G-Baumstamm (Beitrag 1167092)
Um das Pferd mal von hinten aufzuzäumen: Gibt es irgendeine Möglichkeit die Events der Form an sich auszulagern ? Also die Berechnungen so laufen zu lassen wie bis jetzt, aber klicken auf Buttons etc in nem extra Thread zu behandeln ? Wäre sicherlich einfacher ...

Erst in Windows RT. :zwinker: Ansonsten brauchst du explizit Threads. Solange das sauber umgesetzt wird, muss am Code auch nicht viel geändert werden.

Es sei denn du hast das nicht ordentlich gekapselt und greifst auf GUI-Elemente in deinen Download-Funktionen zu. Das wiederum macht weder ohne noch mit Threads Sinn. Und im Thread knallt es dann, wenn du unsynchronisiert zugreifst.

G-Baumstamm 18. Mai 2012 15:04

AW: IdHttp.Get & Geschwindigkeit
 
Zitat:

Zitat von Daniel (Beitrag 1167099)
Ein TidHTTP.Get() ist wenigstens nicht pauschal um den Faktor 5 langsamer, da muss also irgendwo noch der Wurm drin sein - den Du aber meiner Ansicht leichter entdecken wirst, wenn Du Dich vorerst von Threads fern hältst.

Ich habe nochmal versucht das ein bisschen einzugrenzen, wahrscheinlich liegt es doch am Server. Im Schnitt dauert die Verarbeitung etwa 2,5 Sekunden (was in etwa mit dem FF vergleichbar ist, er zeigt die Seite zwar relativ schnell an, bis das Laden-Symbol weggeht könnten es aber tatsächlich 2 Sekunden sein), allerdings gibt es hin und wieder Einbrüche, so dass das Laden 5-6 Sekunden dauert, das ist aber wahrscheinlich dann serverseitig ...

Zitat:

Zitat von jaenicke (Beitrag 1167109)
Es sei denn du hast das nicht ordentlich gekapselt und greifst auf GUI-Elemente in deinen Download-Funktionen zu. Das wiederum macht weder ohne noch mit Threads Sinn. Und im Thread knallt es dann, wenn du unsynchronisiert zugreifst.

Wo der Mann Recht hat, hat er Recht ... mir war nicht klar, dass man über andere Threads nicht auf die GUI zugreifen kann, und ShowMessage auch kein gutes Tool zur Fehlerbehebung in Threads ist ... ;)

Hab jetzt nur die tatsächliche Problem-Prozedur im Thread & damit gehts ohne Fehler. Frage wäre jetzt nur noch, wie ich herausfinde, wenn der Thread fertig ist, im Moment setze ich am Ende des Executes ne Variable auf true, und habe im anderen thread ne while-Schleife, die so lange sinnlos herumrattert bis die Variable true ist ... das geht doch bestimmt noch eleganter.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:38 Uhr.
Seite 1 von 2  1 2      

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