Über den MT5-Code-Profiler

 

Ich habe begonnen, einen neuen Profiler zu verwenden. In diesem Abschnitt könnten wir Informationen über die ordnungsgemäße Nutzung des Systems zusammenfassen.

Zunächst einmal habe ich einige Fragen zu seltsamen Dingen in Bezug auf die vom Profiler zurückgegebenen Daten.

Der Profiling-Bericht, der in einem EA verwendet wird, der auf historischen Daten läuft:

2021.07.08 15:43:06.269  MQL5 profiler 139098  total measurements, 0/0 errors, 320 mb of stack memory analyzed (92848/1073741824)

2021.07.08 15:43:06.269 MQL5 profiler 982065 total function frames found (279627 mql5 code, 122460 built-in,571051 other, 8927 system)

Ergebnisse (Funktionen nach Aufruf):

Q1. Der Bericht sagt 139098 Messungen, aber OnTick () Total CPU ist 150026, wie ist das möglich? (aber CopyHistoryData 80087 als 57,58% richtig bedeutet 100% = 139098).

Q2. Der Bericht spricht von 571.051 anderen "Funktionen". Was sind diese Funktionen, wenn es sich nicht um mql, eingebettete oder Systemfunktionen handelt?

Q3. CopyHistoryData zeigt 80087 Gesamt-CPU, wobei 3 gemeldete Funktionsaufrufe (CopyHigh, CopyLow, CopyTime) unterschiedliche Gesamt-CPU aufweisen, ok. Die native CPU für diese Funktionen ist jedoch gleich und entspricht der Gesamt-CPU (Aufrufstapel). Dies scheint falsch zu sein, da bei 80087 (Stapel) für CopyHistoryData die Summe für 3 Funktionen 62.161 (44286 + 9448 + 8427) beträgt. Wie kann es sein, dass bei 62.161 Aufrufen 80.087 Pausen in diesen 3 Funktionen erkannt werden? Unmöglich, die einzige Erklärung ist, dass diese Zahl für CopyHistoryData global ist und daher nutzlos. Habe ich etwas verpasst?

 

Backtest läuft bei:

2021.07.10 08:00: 37.101 Core 01 EURUSD, H1: 230861 Ticks, 998 generierte Bars. Der Test wurde in 0: 03: 09.367 bestanden (einschließlich der Vorverarbeitung der Ticks 0: 00: 00.515).

Ich habe Code hinzugefügt, um die Ausführungszeit von SymbolInfoTick () mit GetMicrosecondCount () zu messen.

       ulong start= GetMicrosecondCount ();

       //--- Get tick information
       if (! SymbolInfoTick (symbol,tick))
         return ( false );

      BENCH += GetMicrosecondCount ()-start;

Ergebnis:

2021.07.10 08:00: 37.101 Core 01 2021.05.30 23:59:59 Gesamt = 1209572 Ausgeführt = 836973 in 661874 Mikrosekunden

So benötigte SymbolInfoTick () für die historischen Daten in 3 Minuten und 9 Sekunden insgesamt 661 Millisekunden. Der Profiler zeigt jedoch, dass er 74,71 % der Messungen nutzt. Wie genau oder nützlich das ist, weiß ich nicht.

 

Ein weiteres Beispiel für seltsame Daten.

Laut der globalen Statistik war SymbolInfoTick () 209 Mal im Aufrufstapel. Aber innerhalb des Codes steht 210. Gute Präzision.

Laut der globalen Statistik wird SymbolInfoTick 209 Mal abgetastet (das sind 0,83 % aller Abtastungen). GUT. Jetzt sagen die Codedaten, dass es 1 Mal erreicht wird (das sind jetzt 1,49 %, wenn man sich also die andere Gesamtzahl ansieht, wie hoch ist sie?) Nach der Berechnung bedeutet 1 gleich 1,49 %, dass die Gesamtzahl (100 %) 67 beträgt. Somit beziehen sich 1,49 % auf OnTimer (), die in diesem Fall die Hauptfunktion ist. Aber wie kann es sein, dass es dort 1 gibt und in der Gesamtstatistik 209?

Selbst wenn es kein Fehler ist, wie kann es schnell nützlich sein (was ein Profiler meiner Meinung nach sein sollte)?

 

Eine weitere

Dies ist eine Code-Zeile über SymbolInfoTick (), wie bereits gezeigt. Eine Zuweisung wie newTick = false wurde also 5 Mal "ausgewählt"! Weitere 5 Mal nach dem Aufruf von SymbolInfoTick () ( 1 - 1,49%)? Scherz beiseite ?

 
Es muss sich um einen Fehler handeln, wenden Sie sich an den Service Desk.
 

Fragen Sie sich, was es ist und worin der Unterschied besteht:

  • Sampling-basiertes Profiling (wie wir es jetzt haben, ähnlich wie bei Visual Studio C++ und anderen)
  • Auf Code-Tooling basierende Profilerstellung (wie wir es früher gemacht haben)

 
Renat Fatkhullin :

Fragen Sie sich, was es ist und worin der Unterschied besteht:

  • Sampling-basiertes Profiling (wie wir es jetzt haben, ähnlich wie bei Visual Studio C++ und anderen)
  • Profiling auf der Grundlage von Code-Instrumentierung (wie zuvor)

Der Unterschied ist offensichtlich.

Das Problem ist die Anwendung in der Praxis mit inkonsistenten Daten und Fehlern.

 
Alain Verleyen:

Ein weiteres Beispiel für seltsame Daten.

Laut der globalen Statistik war SymbolInfoTick () 209 Mal im Aufrufstapel. Aber innerhalb des Codes steht 210. Gute Präzision.

Laut der globalen Statistik wird SymbolInfoTick 209 Mal abgetastet (das sind 0,83 % aller Abtastungen). GUT. Jetzt sagen die Codedaten, dass es 1 Mal erreicht wird (das sind jetzt 1,49 %, wenn man sich also die andere Gesamtzahl ansieht, wie hoch ist sie?) Nach der Berechnung bedeutet 1 gleich 1,49 %, dass die Gesamtzahl (100 %) 67 beträgt. Somit beziehen sich 1,49 % auf OnTimer (), die in diesem Fall die Hauptfunktion ist. Aber wie kann es sein, dass es dort 1 gibt und in der Gesamtstatistik 209?

Selbst wenn es kein Fehler ist, wie kann es schnell nützlich sein (was ein Profiler meiner Meinung nach sein sollte)?

Der Screenshot zeigt die Statistik für die aufrufende Zeichenfolge, nicht für die Funktion SymbolInfoTick.

Insgesamt wurde die angegebene Zeichenkette 210 Mal gemessen, wenn genau auf der Zeichenkette ein "Stop" war, vor dem Aufruf von SymbolInfoTick oder kurz danach, und 209 Mal als Rückgabestring von SymbolInfoTick

 
Alain Verleyen:

Eine weitere

Dies ist eine Code-Zeile über SymbolInfoTick (), wie bereits gezeigt. Eine Zuweisung wie newTick = false wurde also 5 Mal "ausgewählt"! Weitere 5 Mal nach dem Aufruf von SymbolInfoTick () ( 1 - 1,49%)? Scherz beiseite ?

Ich verstehe nicht ganz, was da geschrieben steht.

Um diesen Screenshot zu lesen: die Zeichenfolge wurde 5 Mal "angehalten", von der Gesamtlast sind das 0,06%, für den Code der Funktion, zu der die Zeichenfolge gehört, sind das 7,46%


 

Der Zähler "Self CPU" zeigt die Auswirkung des String-Codes auf die Geschwindigkeit der Funktion an, in der sich der String befindet.
Wichtig ist, dass die Zeit der Funktion, die in der Zeichenkette aufgerufen wird, nicht von diesem Zähler gezählt wird, vielleicht ist das falsch.


Der "Total CPU"-Zähler zeigt die Auswirkung des String-Codes auf das gesamte Programm, und dieser Zähler berücksichtigt die im String aufgerufenen Funktionen.

 
Ilyas :

Ich verstehe nicht ganz, was da steht.

Sie sollten diesen Screenshot folgendermaßen lesen: Die Zeile wird 5 Mal "angehalten", was 0,06 % der Gesamtlast entspricht, für den Code der Funktion, zu der die Zeile gehört, sind es 7,46 %.


Ja, ich weiß. (Entschuldigen Sie bitte meinen Tonfall, ich war ein bisschen wütend).

Das Problem ist:

      newTickф  = false ;                     // Total CPU : 5 (0.06%)    Self CPU : 5 (7.46%)

bis jetzt

       if (! SymbolInfoTick (symbolф,tickф))     // Total CPU : 210 (2.57%)  Self CPU : 1 (1.49%)

Allgemeine CPU ist in Ordnung.

Aber wie ist es bei Self CPU möglich, dass "newTick = false" gleich 5 und ein Funktionsaufruf wie SymbolInfoTick () nur gleich 1 ist? Das ergibt für mich keinen Sinn.