Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 50

 
fxsaber:

Questo è un problema minore. Sì, l'ottimizzatore del compilatore non sa ancora come ottimizzare tali momenti di stringa. Ma è l'assegnazione delle stringhe che è il problema del rallentamento.

Credo che sia il principale. Cosa sarebbe più efficiente: un'assegnazione delle stringhe più veloce o la sua esclusione dal codice? Certo, ci sono casi in cui abbiamo bisogno dell'assegnazione delle stringhe di per sé, ma quanto spesso ne abbiamo bisogno? Nella maggior parte dei casi, abbiamo a che fare solo con variabili temporanee.

E quanto velocemente queste operazioni con le stringhe possono essere implementate è anche una questione. Lo fai sembrare come se potesse essere accelerato molte volte. Ne dubito. Hanno già ottimizzato-sovra-ottimizzato tutto lì molte volte. Supponiamo che riescano a spremere un altro 20-30%, non farà differenza.

A proposito, non hai provato a dichiarare la variabile stringa come costante?

Quindi se stai scrivendo qualcosa come questo.

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

è sempre meglio spingere la clausola OrderSymbol alla fine della condizione generale.

Beh, naturalmente. E non ha niente a che fare con OrderSymbol o MQL. Le operazioni con le stringhe sono costose di per sé, quindi non dovreste usarle invano.

 

E così nel mezzo

fxsaber:

Per esempio, se eseguiamo una corsa in tick reali su FIBO per un mese, sarà di circa 1 milione di tick. Se ad ogni tick si ottiene il valore di PositionGetString e lo si confronta con qualcosa, la performance sarà accettabile, ma se si assegna prima il risultato della funzione ad una variabile stringa prima di confrontarla e poi la si confronta, la durata di esecuzione aumenterà di circa un secondo.


Se sembra una piccola cosa, è una visione sbagliata. Quando un tale EA viene eseguito in modalità di ottimizzazione per diverse migliaia di passaggi, quel secondo in più si traduce in ore aggiuntive di tempo di attesa. Cioè un'innocua assegnazione di stringhe può causare ore di attesa aggiuntive durante l'ottimizzazione. Fate attenzione e tenete conto di questa sfumatura.

Spero che tu stesso capisca che questo approccio è altamente inefficiente. Perché dovremmo ottenere PositionGetString ad ogni tick? Cosa può cambiare lì? Soprattutto considerando che lei stesso ha aperto questa posizione, cioè tutto è già noto in anticipo.

Quindi, se stiamo parlando di ottimizzare le prestazioni, allora dobbiamo prima ottimizzare la logica del programma stesso.

 
Alexey Navoykov:

E quanto velocemente queste operazioni di stringa possono essere accelerate è anche una questione. Lo fai sembrare come se potesse essere accelerato molte volte. Ne dubito. Hanno già ottimizzato-sovra-ottimizzato tutto lì molte volte. Anche se riuscite a spremere il 20-30% in più, non farà la differenza.

A volte.

A proposito, non avete provato a dichiarare una variabile stringa come una costante?

Sì, l'ho fatto.
 
Alexey Navoykov:

Perché ottenere PositionGetString ad ogni tick? Cosa può cambiare lì? Soprattutto considerando che tu stesso hai aperto questa posizione, cioè tutto è già noto in anticipo.

Bene, se stiamo parlando di ottimizzare le prestazioni, allora dobbiamo prima ottimizzare la logica del programma stesso.

Un robot da combattimento con tale logica: non ci dovrebbero essere posizioni aperte su EURUSD in tale intervallo di tempo. Se ce ne sono, chiudeteli.

Hai una posizione aperta su GBPUSD. Come possiamo soddisfare la condizione di cui sopra senza controllare OrderSymbol ad ogni tick?

O suggerisci di scrivere una versione speciale dell'Expert Advisor solo per il tester? Qui, una persona ha comprato un robot da combattimento e lo sta testando. Come spiegare al mercato che tutto è ottimizzato dalla velocità?

 
fxsaber:

Un robot da combattimento con questa logica - non ci dovrebbero essere posizioni aperte in EURUSD in questo intervallo di tempo. Se ci sono, chiudeteli.

Hai una posizione aperta su GBPUSD. Come possiamo soddisfare la condizione di cui sopra senza controllare OrderSymbol ad ogni tick?

O suggerisci di scrivere una versione speciale dell'Expert Advisor solo per il tester? Qui, una persona ha comprato un robot da combattimento e lo sta testando. Dovremmo scrivere nel Market che tutto è ottimizzato appositamente per la velocità del tester?

Bene, è sufficiente controllare solo i ticket delle posizioni attualmente aperte (e quindi mantenere un array di essi). Se c'è un nuovo biglietto, allora tutti gli altri controlli devono essere effettuati con esso. Perché dovremmo controllare la stessa cosa un milione di volte?

A proposito, MQL5 ha eventi commerciali. Pertanto, non c'è bisogno di controllarlo ad ogni spunta.

 
Alexey Navoykov:

Bene, è sufficiente controllare solo i ticker delle posizioni aperte correnti (e mantenere un array di essi di conseguenza).

Questo non sarà molto più economico.

E a proposito, MQL5 ha eventi commerciali. Pertanto, non c'è bisogno di controllare ogni zecca.

A volte vengono scritte soluzioni multipiattaforma. Inoltre, non c'è e non può esserci alcuna garanzia di ottenere tutti gli eventi commerciali.

 
fxsaber:

Non sarebbe molto più economico.

La differenza tra le operazioni intere non è molto più economica delle operazioni con le stringhe? Beh, fate come volete.

 
Alexey Navoykov:

La differenza tra le operazioni intere non è molto più economica delle operazioni con le stringhe? Beh, fate come volete.

Non vedo perché ne abbiate bisogno, ma mi avete lasciato perplesso. E sono d'accordo che l'opzione con una serie di biglietti sarebbe più produttiva.

È vero, dal punto di vista di una certa logica, una tale variante sembra molto artificiale, posata su una sfumatura tecnica, piuttosto che su una costruzione logica del programma.

Ma ne terrò conto lo stesso. Naturalmente, non ho mai incontrato questo approccio in kodobase.

 

La mancanza di eredità multipla in MQL è deprimente, naturalmente. Tuttavia, potete farlo funzionare in ogni modo possibile - con modelli e macro - non ne avrete bisogno )

Ecco quello che ho fatto. Tutte le classi sorgente dovrebbero essere dichiarate come modelli che definiscono la classe madre.

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);
}

Naturalmente, ci sono alcune sottigliezze, legate al fatto che le classi sono ereditate sequenzialmente (nell'ordine che abbiamo impostato), piuttosto che simultaneamente (come nella vera eredità multipla). In particolare, avranno priorità diverse quando si verifica un sovraccarico. Inoltre, se una stessa classe template partecipa più volte alla catena di ereditarietà, saranno classi completamente diverse, che non sono collegate tra loro in alcun modo. Quindi dobbiamo stare attenti. Ma non c'è nessun problema con le interfacce, si può ereditare senza restrizioni.

 
Alexey Navoykov:

La mancanza di eredità multipla in MQL è deprimente, naturalmente. Tuttavia, potete farlo funzionare in ogni modo possibile - con modelli e macro - non ne avrete bisogno )

Ecco quello che ho fatto. Tutte le classi sorgente dovrebbero essere dichiarate come modelli che definiscono la classe madre.

Naturalmente, ci sono alcune sottigliezze, legate al fatto che le classi sono ereditate sequenzialmente (nell'ordine che abbiamo impostato), piuttosto che simultaneamente (come nella vera eredità multipla). In particolare, avranno priorità diverse quando si verifica un sovraccarico. Inoltre, se una stessa classe template partecipa più volte alla catena di ereditarietà, saranno classi completamente diverse, non collegate tra loro in alcun modo. Quindi dobbiamo stare attenti. Ma non ci sono problemi con le interfacce, si può ereditare senza limitazioni.

È un buon trucco. Il trucco sta tutto nell'applicare il modello a TParent. Non l'ho mai visto così.