Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Performance Messung der Unit-Initialisierungsphase (https://www.delphipraxis.net/204081-performance-messung-der-unit-initialisierungsphase.html)

HeZa 22. Apr 2020 08:15

Performance Messung der Unit-Initialisierungsphase
 
Hallo,

um die Startzeit einer Anwendung bis zum Erzeugen der ersten Form zu analysieren, suche ich nach einem allgemeinen Weg, die Zeit jeder einzelnen Unit im Initialisierungsteil zu messen. Insbesondere auch für Delphi und 3rd-Party Bibliotheken.

Hat das schon Mal jemand gemacht?

Ciao HeZa

ULIK 22. Apr 2020 08:38

AW: Performance Messung der Unit-Initialisierungsphase
 
Wie wäre es ganz simple mit Logging eines Timestamps? Die Initialisierung des Loggings als allererste Unit einbinden ins Projekt und dann in den jeweiligen Initialisierungsabschnitten die differenzen der TimeStamps loggen?
Oder man verwendet Profiler für so etwas (z.B. AQTime)

HeZa 22. Apr 2020 10:28

AW: Performance Messung der Unit-Initialisierungsphase
 
Es sind ca. 2100 Units, davon 850 eigene. Insbesondere im Source der Delphi und 3rd-Party Units möchte ich nicht rumfummeln.

Gab es oder gibt es nicht von AQTime eine Version die man als Delphi-User ohne weitere Lizenzkosten nutzen konnte?

ULIK 22. Apr 2020 10:43

AW: Performance Messung der Unit-Initialisierungsphase
 
Was willst Du eigentlich genau erreichen? Die wenigsten Units werden beim Start in Initialisierungsteil etwas stehen haben und wenn dann eher kurze Sachen. Wenn der Start der Anwendung zu lange dauert, dann schau erst mal in deine eigene Units rein, was die so treiben.
Beschreib doch einfach mal, was dein Problem ist. Ich habe auch mit der Startzeit einer Anwendung zu kämpfen und die Erfahrung lehrt, daß das Problem meist nicht da ist, wo man meint.

Was AQTime betrifft: es gab zumindest mal eine reduzierte Version mit Delphi. Ob die allerdings auch Initialisierungsbereiche messen kann, weiß ich nicht. Wenn's wirklich kritisch ist, dann ist auch der Preis von AQTime zu verschmerzen (auch wenn ich deren Lizenzmodell jetzt auch ned so toll finde).

Uwe Raabe 22. Apr 2020 11:24

AW: Performance Messung der Unit-Initialisierungsphase
 
Die einzelnen initialization Abschnitte der Units werden von der Prozedur InitUnits in System.pas aufgerufen. Dort könntest du mit dem Debugger ja mal auf die Suche gehen.

Ein generelles Timing dieser Aufrufe ist aber wohl nicht so einfach möglich. Ich würde auch eher in den eigenen Units nach Problemen suchen.

TurboMagic 22. Apr 2020 14:40

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von HeZa (Beitrag 1462648)
Es sind ca. 2100 Units, davon 850 eigene. Insbesondere im Source der Delphi und 3rd-Party Units möchte ich nicht rumfummeln.

Gab es oder gibt es nicht von AQTime eine Version die man als Delphi-User ohne weitere Lizenzkosten nutzen konnte?

Ja, die gab es zumindest mal.
Evtl. gibt's auch eine Demo Version die man mal kurz ausprobieren könnte.

stahli 22. Apr 2020 15:13

AW: Performance Messung der Unit-Initialisierungsphase
 
AQTime Pro hat den Vorteil, dass man das Tool extern außerhalb Delphi nutzen kann (seine Anwendung also innerhalb AQTime analysiert, ohne Delphi laufen zu haben).

Ich fand das damals deutlich komfortabler und stabiler - also lohnenswert.

himitsu 22. Apr 2020 15:32

AW: Performance Messung der Unit-Initialisierungsphase
 
Nja, ob in der IDE oder nicht.
Das einzige Problem was wir hatten, war dass innerhalb der IDE öfters unerklärliche Exceptions auftraten, innerhalb der AQTime-BPLs/DLLs, selbst wenn man das Ding grad garnicht benutzte.

Auch daher ist es außerhalb der IDE wirklich um Längen angenehmer.


Im Programm selbst was machen zu wollen ist unschön.
Erstmal ist es nicht so einfach sich dort reinzuhängen (der Uwe sagte schon, wo man dazu was finden kann),
und dann muß an seinen Code auch sehr früh laden/ausführen, um sich reinzuhängen, bevor das Meiste schon durch ist. (und bei Verwendung der RTL/VCL-Packages ist das praktisch unmöglich)


Tipp: Falls du innerhalb des Programms wissen willst, dann deine EXE gestartet wurde, also zum Berechnen der Dauer, dann siehe Bei Google suchenGetProcessTimes.

HeZa 23. Apr 2020 07:37

AW: Performance Messung der Unit-Initialisierungsphase
 
Hallo,

Danke erstmal für die Antworten.

Eigene Units sind bestimmt gute Kandidaten und tatsächlich gibt es auch bereits Vermutungen, aber ich hätte gerne an unsere interne Diskussion etwas mehr Substanz gebracht in Form von Messungen. Ich hatte gehofft, dass es da einen einfachen Weg gibt. So sieht es aber erst mal nicht aus. Es sei denn, es kann jemand bestätigen, dass man AQTime die Laufzeit der Initialisierungsabschnitte von Delphi-Units messen kann?

Wie gesagt treten die Probleme unter Terminalserver auf. Einiges erklärt sich durch die aktuell höhere Last, aber eben nicht alles.

Ein Verdachtskandidat der an mich herangetragen wurde ist EurekaLog in der Version 7.4.0.0 und die neuere Version 7.6.6.43 soll Abhilfe schaffen.
Ein anderer Kandidat ist CrystalNet, dass wir für eine Kommunikation mit einer DotNet Komponente brauchen. Hier ist die Vermutung, dass CrystalNet in der Startphase die ganze DotNet Umgebung Initialisiert.

Ich nehme erstmal den Tipp von Himitsu mit, die Zeit bis zum ersten Dialog via GetProcessTimes zu dokumentieren.

Ciao HeZa

Lemmy 23. Apr 2020 09:55

AW: Performance Messung der Unit-Initialisierungsphase
 
Performanceprobleme mit Vermutungen zu lösen ist meist eine schlechte Idee.

Ein erster Weg kann wirklich sein, mit GetTickCount und CO Zeiten zu messen.

Ein Problem bleibt: auch wenn eine Funktion nur 3-4 ms für einen Lauf braucht, kann die am Ende für eine extrem lange wartezeit verantwortlich sein, wenn die entsprechend oft aufgerufen wird.

Ich verwende bei solch nicht trivialen Dingen sehr gerne http://www.prodelphi.de/
Auch, wenn das den Sourcecode verändert - aber das ist in Zeiten SVN, git und co meiner Meinung keine Ausrede mehr. Vor allem ist ProDel mit 60-70€ echt ein Schnäppchen...

Uwe Raabe 23. Apr 2020 10:43

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von Lemmy (Beitrag 1462750)
Ein Problem bleibt: auch wenn eine Funktion nur 3-4 ms für einen Lauf braucht, kann die am Ende für eine extrem lange wartezeit verantwortlich sein, wenn die entsprechend oft aufgerufen wird.

Für den Unit-Initialization Code sollte das egal sein. Der wird immer nur einmal aufgerufen.

himitsu 23. Apr 2020 11:09

AW: Performance Messung der Unit-Initialisierungsphase
 
Ach ja, bei uns haben wir inzwischen nahezu alles "Schlimme" aus den unseren Initialization'en rausgenommen.
Stattdessen gibt es überall Class-Function ModulInitialize (in der Hauptklasse dieser Unit, bzw. des Package), die wir dann in einer zentralen Stelle der EXE aufrufen.

Erstmal hatten wir das Problem, dass wir hier massig BPLs haben und wenn es dann irgendwo hing, war es schwer zu finden.
So haben wir eine Funktion, die man "gemütlich" debuggen kann und wo sich "einfacher" eine gemeinsame Fehlerbehandlug einbauen ließ.
Unter anderem eine Fortschrittsvariable, die für die großen Zwischenschritte mit einem Namen gefüllt wird.
Einmal für die Fortschrittsanzeige beim Start und auch für den Fehlertext im großen Try-Except um alles drumrum.

Für die großen bekannten Fehlerstellen kann uns ein "Benutzer" diesen Namen am Telefon einfach nennen, ohne Eurekalog vorlesen zu müssen/können.
z.B. Acrobat zickt mal wieder rum oder das Font-Registrieren hängt mal wieder, weil MS-Office sich dämlich überall reinhängt.

Rollo62 23. Apr 2020 11:22

AW: Performance Messung der Unit-Initialisierungsphase
 
Die class constructoren sind ja im Prinzip auch initialization Bereiche in einer Unit.
Wann genau werden die eigentlich aufgerufen, ich vermute mal NACH dem initialization Teil.

himitsu 23. Apr 2020 11:43

AW: Performance Messung der Unit-Initialisierungsphase
 
Class Conscrutctor direkt vor dem Initialization seiner Unit, in der Reihenfolge der Deklaration der Klassen.

Hab nicht nachgesehn, ob die das über die RTTI suchen, oder ob der Compiler den Aufruf implizit in das Initialization reinschreibt.
Beim Class Desctructor genau andersrum, also am Ende des Finalization.

Aber schön am Class Constructor ist, dass es nur gemacht wird, wenn die Klasse irgendwo verwendet wurde.
Und nicht wie beim Initialization, wo der manuelle Aufruf die Klasse immer mit reinzieht, egal ob sie verwendet wird.
Deswegen, und weil Ressourcen nicht benutzungsabhängig eingebunden werden können, ist die EXE mit der VCL so rießig.

HeZa 23. Apr 2020 12:57

AW: Performance Messung der Unit-Initialisierungsphase
 
Hallo,

Zitat:

Zitat von himitsu (Beitrag 1462759)
Aber schön am Class Constructor ist, dass es nur gemacht wird, wenn die Klasse irgendwo verwendet wurde.
Und nicht wie beim Initialization, wo der manuelle Aufruf die Klasse immer mit reinzieht, egal ob sie verwendet wird.

das klingt nach einem sehr interessanten Vorteil.

Ciao HeZa

TurboMagic 23. Apr 2020 13:34

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1462753)
Zitat:

Zitat von Lemmy (Beitrag 1462750)
Ein Problem bleibt: auch wenn eine Funktion nur 3-4 ms für einen Lauf braucht, kann die am Ende für eine extrem lange wartezeit verantwortlich sein, wenn die entsprechend oft aufgerufen wird.

Für den Unit-Initialization Code sollte das egal sein. Der wird immer nur einmal aufgerufen.

Jein: wenn du da eine Schleife reinbaust die 1000x etwas aufruft was jeweils 3-4ms benötigt, dann geht da auch die Zeit für flöten...

dummzeuch 23. Apr 2020 13:48

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von himitsu (Beitrag 1462759)
Beim Class Desctructor genau andersrum, also am Ende des Finalization.

Ist das nicht vor dem Aufruf der finalization?

himitsu 23. Apr 2020 14:01

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von dummzeuch (Beitrag 1462770)
Ist das nicht vor dem Aufruf der finalization?

Glaub nicht.

Es wäre ja auch sonst etwas unpraktisch, wenn du im Finalization auf die Klasse zugreifen willst. :stupid:
Ist wie beim Inherited, im Constructor macht man das zuerst und im Destructor (meistens) zuletzt. :zwinker:

TigerLilly 23. Apr 2020 15:02

AW: Performance Messung der Unit-Initialisierungsphase
 
https://www.nexusdb.com/support/inde...q=qualitysuite

Kann ich sehr empfehlen, wenn es ums Profiling geht.

Rollo62 23. Apr 2020 16:30

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von himitsu (Beitrag 1462759)
Class Conscrutctor direkt vor dem Initialization seiner Unit, in der Reihenfolge der Deklaration der Klassen.

OK, auf den zweiten Blick macht das auch mehr Sinn.
Die initialisations können ja auch wieder class procedures aufrufen, wie unten als Vorschlag,
dann wäre es gut wenn diese Klassen schon vor-construiert wären.

dummzeuch 23. Apr 2020 17:32

AW: Performance Messung der Unit-Initialisierungsphase
 
Zitat:

Zitat von himitsu (Beitrag 1462773)
Zitat:

Zitat von dummzeuch (Beitrag 1462770)
Ist das nicht vor dem Aufruf der finalization?

Glaub nicht.

Es wäre ja auch sonst etwas unpraktisch, wenn du im Finalization auf die Klasse zugreifen willst. :stupid:
Ist wie beim Inherited, im Constructor macht man das zuerst und im Destructor (meistens) zuletzt. :zwinker:

Ich hab's gerade getestet, mit einem Console-Program, welches jeweils WriteLn aufruft:

Code:
TMyClass.CConstructor
initialization
Main.Begin
TMyClass.Create
TMyClass.Destroy
Main.end
finalization
TMyClass.CDestructor
Du hast also Recht.

himitsu 23. Apr 2020 17:44

AW: Performance Messung der Unit-Initialisierungsphase
 
In der Hinsicht ist vieles von der Reihenvolge vorhersehbar, dank des Single-Pass-Compilers, der eh nicht anders kann.

Auch was die verschachtelten Unist betrifft.
  • Units (Uses) im Interface werden immer vor der Unit initialisiert, wo sie eingebunden wurden (denn wenn man im initializazion auf was davon zugreift, dann muss es schon da sein)
  • aber Units im Uses der Implemetation ... da ist es Zufall (kann davor, der auch erst danach)
    • Zufall = das was der Compiler zuerst findet, wird zuerst gemacht (mit Ausnahme dass vorher noch das im Interface erst alles gemacht wird),
    • wobei es andersrum wohl einfacher zu verstehen ist:
      das was der Compiler zuletzt findet und was nicht durch das obere USES schon gemacht wurde, das kommt auch als Letztes


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