Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 50

 
fxsaber:

Dies ist ein kleines Problem. Ja, der Compiler-Optimierer weiß noch nicht, wie er solche String-Momente optimieren soll. Das Problem der Verlangsamung liegt jedoch in der Zuweisung der Zeichenketten.

Ich glaube, es ist die wichtigste. Was wäre effizienter: eine schnellere Zuweisung von Zeichenketten oder deren Ausschluss aus dem Code? Sicherlich gibt es Fälle, in denen wir die String-Zuweisung an sich benötigen, aber wie oft brauchen wir sie? In den allermeisten Fällen haben wir es nur mit temporären Variablen zu tun.

Und wie schnell diese String-Operationen durchgeführt werden können, ist auch eine Frage. Bei Ihnen klingt das so, als ob man das um ein Vielfaches beschleunigen könnte. Das bezweifle ich. Sie haben dort bereits alles um ein Vielfaches über-optimiert. Angenommen, es gelingt ihnen, weitere 20-30 % herauszuquetschen, so wird das keinen Unterschied machen.

Übrigens, haben Sie nicht versucht, die String-Variable als Konstante zu deklarieren?

Wenn Sie also etwas wie das hier schreiben.

if ((OrderSymbol() == Symb) && (OrderMagicNumber == Magic))

es ist immer besser, die OrderSymbol-Klausel an das Ende der allgemeinen Bedingung zu schieben.

Nun ja, natürlich. Und es hat nichts mit OrderSymbol oder MQL zu tun. String-Operationen sind an sich schon teuer, daher sollte man sie nicht umsonst verwenden.

 

Und so zwischendurch

fxsaber:

Wenn wir z. B. einen Monat lang einen echten Tick-Lauf auf der FIBO durchführen, werden es etwa 1 Million Ticks sein. Wenn Sie bei jedem Tick den Wert von PositionGetString abrufen und mit etwas vergleichen, ist die Leistung akzeptabel. Wenn Sie jedoch das Ergebnis der Funktion zunächst einer String-Variablen zuweisen und dann vergleichen, erhöht sich die Laufzeit um etwa eine Sekunde.


Wenn es wie eine Kleinigkeit aussieht, ist das eine falsche Vorstellung. Wenn ein solcher EA im Optimierungsmodus für mehrere tausend Durchläufe ausgeführt wird, bedeutet diese zusätzliche Sekunde zusätzliche Stunden an Wartezeit. D.h. eine harmlose String-Zuweisung kann bei der Optimierung zusätzliche Stunden Wartezeit verursachen. Seien Sie vorsichtig und berücksichtigen Sie diese Nuance.

Ich hoffe, Sie verstehen selbst, dass dieser Ansatz sehr ineffizient ist. Warum sollten wir PositionGetString bei jedem Tick erhalten? Was kann sie dort ändern? Vor allem, wenn man bedenkt, dass Sie selbst diese Stelle eröffnet haben, d.h. alles schon vorher bekannt ist.

Wenn wir also von Geschwindigkeitsoptimierung sprechen, müssen wir zuerst die Programmlogik selbst optimieren.

 
Alexey Navoykov:

Und wie schnell diese String-Operationen beschleunigt werden können, ist auch eine Frage. Bei Ihnen klingt es so, als ob es um ein Vielfaches beschleunigt werden kann. Das bezweifle ich. Sie haben dort bereits alles um ein Vielfaches über-optimiert. Selbst wenn es Ihnen gelingt, 20-30 % mehr herauszuholen, wird das keinen Unterschied machen.

Zeitweise.

Übrigens, haben Sie nicht versucht, eine String-Variable als Konstante zu deklarieren?

Ja, das habe ich.
 
Alexey Navoykov:

Warum PositionGetString bei jedem Tick abrufen? Was kann sich dort ändern? Vor allem, wenn man bedenkt, dass Sie diese Stelle selbst eröffnet haben, d.h. alles bereits im Voraus bekannt ist.

Nun, wenn wir über die Optimierung der Leistung sprechen, dann müssen wir zuerst die Programmlogik selbst optimieren.

Ein Kampfroboter mit einer solchen Logik: In einem solchen Zeitintervall sollte es keine offenen Positionen auf EURUSD geben. Wenn es welche gibt, schließen Sie sie.

Sie haben eine offene GBPUSD-Position. Wie können wir die obige Bedingung erfüllen, ohne OrderSymbol bei jedem Tick zu überprüfen?

Oder schlagen Sie vor, eine spezielle Version des Expert Advisors nur für den Tester zu schreiben? Hier hat eine Person einen Kampfroboter gekauft und testet ihn. Wie kann man auf dem Markt erklären, dass alles auf Geschwindigkeit optimiert ist?

 
fxsaber:

Ein Kampfroboter mit dieser Logik - es sollte keine offenen Positionen in EURUSD in diesem Zeitintervall geben. Wenn ja, schließen Sie sie.

Sie haben eine offene GBPUSD-Position. Wie können wir die obige Bedingung erfüllen, ohne OrderSymbol bei jedem Tick zu überprüfen?

Oder schlagen Sie vor, eine spezielle Version des Expert Advisors nur für den Tester zu schreiben? Hier hat eine Person einen Kampfroboter gekauft und testet ihn. Sollen wir in den Market schreiben, dass alles speziell auf Geschwindigkeit für den Tester optimiert ist?

Es reicht aus, nur die Tickets der aktuell geöffneten Positionen zu prüfen (und somit ein Array davon zu führen). Liegt ein neues Ticket vor, müssen alle anderen Kontrollen mit diesem durchgeführt werden. Warum sollten wir dasselbe eine Million Mal überprüfen?

Übrigens, MQL5 hat Handelsveranstaltungen. Es ist daher nicht notwendig, sie bei jeder Zecke zu überprüfen.

 
Alexey Navoykov:

Es reicht aus, nur die Ticker der aktuell offenen Positionen zu überprüfen (und ein entsprechendes Array zu pflegen).

Das wird nicht viel billiger sein.

Übrigens, MQL5 hat Handelsveranstaltungen. Es ist also nicht nötig, jede einzelne Zecke zu überprüfen.

Manchmal werden plattformübergreifende Lösungen geschrieben. Außerdem gibt es keine Garantie dafür, dass alle Fachveranstaltungen stattfinden.

 
fxsaber:

Es wäre nicht viel billiger.

Der Unterschied zwischen Ganzzahl-Operationen ist nicht viel billiger als String-Operationen? Nun, wie Sie wollen.

 
Alexey Navoykov:

Der Unterschied zwischen Ganzzahl-Operationen ist nicht viel billiger als String-Operationen? Nun, wie Sie wollen.

Ich weiß nicht, wozu Sie das brauchen, aber Sie haben mich verblüfft. Und ich muss zustimmen, dass die Option mit einer Reihe von Tickets produktiver wäre.

Aus der Sicht einer gewissen Logik sieht eine solche Variante zwar sehr künstlich aus und beruht eher auf einer technischen Nuance als auf einer logischen Konstruktion des Programms.

Aber ich werde sie trotzdem berücksichtigen. Natürlich ist mir dieser Ansatz in kodobase noch nie begegnet.

 

Das Fehlen der Mehrfachvererbung in MQL ist natürlich deprimierend. Sie können es jedoch auf jede erdenkliche Weise zum Laufen bringen - mit Vorlagen und Makros - Sie werden sie nicht brauchen.)

Das habe ich gemacht. Alle Quellklassen sollten als Vorlagen deklariert werden, die die übergeordnete Klasse definieren.

class CBase { };  // базовый класс

// Макросы, задающие список наследования:

#define  INHERIT1(T)  T<CBase>

#define  INHERIT2(T1, T2)  T2<INHERIT1(T1)>

#define  INHERIT3(T1, T2, T3)  T3<INHERIT2(T1,T2)>

#define  INHERIT4(T1, T2, T3, T4)  T4<INHERIT3(T1,T2,T3)>


// Различные пользовательские классы:

template<typename TParent>
class A : public TParent { public: void a() { Print("A"); } };

template<typename TParent>
class B : public TParent { public: void b() { Print("B"); } };

template<typename TParent>
class C : public TParent { public: void c() { Print("C"); } };


class X : public INHERIT3(A, B, C)  {  };   // Объявляем класс, наследуемый от A, B, C


template<typename T>
void SomeFunc(B<T>& obj)  { obj.b(); }   // Проверочная функция, принимающая класс B


void OnInit()
{
  X x;
  x.a();
  x.b();
  x.c();
  
  SomeFunc(x);
}

Natürlich gibt es einige Feinheiten, die mit der Tatsache zusammenhängen, dass Klassen sequentiell vererbt werden (in der Reihenfolge, die wir festgelegt haben) und nicht parallel (wie bei echter Mehrfachvererbung). Insbesondere bei einer Überlastung haben sie unterschiedliche Prioritäten. Wenn ein und dieselbe Vorlagenklasse mehrmals an der Vererbungskette teilnimmt, handelt es sich außerdem um völlig unterschiedliche Klassen, die in keiner Weise miteinander verwandt sind. Wir müssen hier also vorsichtig sein. Bei Schnittstellen gibt es jedoch kein Problem, sie können ohne Einschränkungen vererbt werden.

 
Alexey Navoykov:

Das Fehlen der Mehrfachvererbung in MQL ist natürlich deprimierend. Sie können es jedoch auf jede erdenkliche Weise zum Laufen bringen - mit Vorlagen und Makros - Sie werden sie nicht brauchen.)

Das habe ich gemacht. Alle Quellklassen sollten als Vorlagen deklariert werden, die die übergeordnete Klasse definieren.

Natürlich gibt es einige Feinheiten, die mit der Tatsache zusammenhängen, dass Klassen nacheinander (in der von uns festgelegten Reihenfolge) und nicht gleichzeitig (wie bei echter Mehrfachvererbung) vererbt werden. Insbesondere bei einer Überlastung haben sie unterschiedliche Prioritäten. Wenn ein und dieselbe Vorlagenklasse mehrmals an der Vererbungskette teilnimmt, handelt es sich außerdem um völlig unterschiedliche Klassen, die in keiner Weise miteinander verwandt sind. Wir müssen hier also vorsichtig sein. Aber es gibt keine Probleme mit Schnittstellen, Sie können ohne Einschränkungen vererben.

Das ist ein guter Trick. Der ganze Trick besteht darin, das Muster auf TParent anzuwenden. Das habe ich so noch nicht gesehen.