Questions sur la POO dans MQL5 - page 87

 
Vladimir Simakov:
Question. Question : Pourquoi avez-vous besoin d'un accordéon ? Si dans une méthode, une classe, en cheval sphérique, oui, dans le vide physique (enfin, je suis bourré )))), alors oui, c'est logique. Et si dans un projet réel, soit une classe au niveau global, ou un loner qui gère tout cela trichomudin (désolé pour le bourbon))))) supplémentaire au début du handler, et, demander directement à partir de lui à n'importe quel endroit))).

c'est un chef de classe qui distribue les tâches et obtient des résultats d'un petit troupeau de classes subordonnées ))))

en général, il est difficile d'expliquer de manière sobre

mais la question est pertinente - comment l'adressage des champs communs est effectué lorsque l'on lit les valeurs de ces champs à partir de méthodes différentes et très souvent

 
Igor Makanu:

c'est un chef de classe qui distribue les tâches et obtient des résultats d'un petit troupeau de classes subordonnées ))))

en général, il est difficile d'expliquer de manière sobre

mais la question est pertinente - comment l'adressage des champs communs est effectué lors de la lecture des valeurs de ces champs à partir de méthodes différentes et très souvent

Regardez. Au début du gestionnaire, quel qu'il soit, vous lancez gSomeGlobal.SomeEvent(...), ou, s'il est unique, Alone::SomeEvent(...), dans cette méthode, vous effectuez la gestion d'état requise et, ensuite, vous demandez simplement les données requises via les getters. Tant que vous n'êtes pas un scalper à haute fréquence, vous pouvez vous foutre de tous les défenseurs de la vitesse, bien qu'il n'y ait pas de frais généraux particuliers ici))).
 
Vladimir Simakov:
Voir aussi. Au début du handler, peu importe lequel, vous lancez gSomeGlobal.SomeEvent(...), ou, s'il est unique, Alone::SomeEvent(...), dans cette méthode vous faites le traitement d'état requis et ensuite vous demandez juste les données requises via les getters. Tant que vous n'êtes pas un scalper à haute fréquence, vous pouvez vous foutre de tous les défenseurs de la vitesse, bien qu'il n'y ait pas de frais généraux particuliers ici))).

les performances de mt5 sont suffisantes pour 10500 ordres par seconde, le canal aurait été suffisant

Je cherchais la vérité, je devais la vérifier... si tu veux faire quelque chose, fais-le toi-même ! ))))

#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"

#define  TST_COUNT 1 e10

#define    SpeedTest(count,msg,EX)   {uint mss=GetTickCount(); ulong lim = count; for(ulong cnt=0;cnt<lim&&!_StopFlag;cnt++){EX;} \
                                    printf("%s: loops = %llu ms=%u",msg,lim,GetTickCount()-mss);}
//+------------------------------------------------------------------+
class A
{
private:
   double            _Ask, _Bid;
   double            f1()  { return(_Ask + 1.0/(1.0+(double)rand())); }
   double            f2()  { return(_Bid + 1.0/(1.0+(double)rand())); }
   double            f3()  { return(_Ask/_Bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ _Ask = tick.ask; _Bid = tick.bid; return(f1() + f2() + f3()); }
};
//+------------------------------------------------------------------+
class B
{
private:
   double            f1(const MqlTick &t)  { return(t.ask + 1.0/(1.0+(double)rand())); }
   double            f2(const MqlTick &t)  { return(t.bid + 1.0/(1.0+(double)rand())); }
   double            f3(const MqlTick &t)  { return(t.ask/t.bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ return(f1(tick) + f2(tick) + f3(tick)); }
};
//+------------------------------------------------------------------+
void OnStart()
{
   A a;
   B b;
   MqlTick rnd_tick;
   for(int i=0; i<5; i++)
   {
      SpeedTest(TST_COUNT, "class A : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = a.calc(rnd_tick);
      );
   
      SpeedTest(TST_COUNT, "class B : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = b.calc(rnd_tick);
      );
   }
}
//+------------------------------------------------------------------+

2020.07.25 18:00:07.293 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 18:00:45.273 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=37968

2020.07.25 18:01:31.405 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 18:02:09.423 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38016

2020.07.25 18:02:55.558 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 18:03:33.635 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38078

2020.07.25 18:04:21.969 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=48344

2020.07.25 18:05:00.113 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38140

2020.07.25 18:05:46.503 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46391

2020.07.25 18:06:24.573 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38062

La vitesse est essentielle pour l'optimisation, c'est pourquoi je voulais en savoir plus.

en général, la référence doit transmettre le prix actuel à toutes les méthodes



UPD :

//+------------------------------------------------------------------+
class C
{
private:
   double            f1(const double &a, const double &b)  { return(a + 1.0/(1.0+(double)rand())); }
   double            f2(const double &a, const double &b)  { return(b + 1.0/(1.0+(double)rand())); }
   double            f3(const double &a, const double &b)  { return(a/b + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){const double ask = tick.ask; const double bid = tick.bid; return(f1(ask,bid) + f2(ask,bid) + f3(ask,bid)); }
};
//+------------------------------------------------------------------+

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37985

 
Igor Makanu:

les performances de mt5 sont suffisantes pour 10500 ordres par seconde, le canal aurait été suffisant

Je cherchais la vérité, je devais la vérifier... si tu veux faire quelque chose, fais-le toi-même ! ))))

2020.07.25 18:00:07.293 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 18:00:45.273 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=37968

2020.07.25 18:01:31.405 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 18:02:09.423 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38016

2020.07.25 18:02:55.558 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 18:03:33.635 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38078

2020.07.25 18:04:21.969 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=48344

2020.07.25 18:05:00.113 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38140

2020.07.25 18:05:46.503 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46391

2020.07.25 18:06:24.573 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38062

La vitesse est essentielle pour l'optimisation, c'est pourquoi je voulais en savoir plus.

en général, la référence doit transmettre le prix actuel à toutes les méthodes



UPD :

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37985

Pour commencer, faites les mêmes conditions de travail)))) Parce que vous avez inséré un opérateur d'assignation absolument inutile (2 pcs), créant ainsi un code sciemment non optimal))).

//+------------------------------------------------------------------+
class A
{
private:
   double            _Ask, _Bid;
   double            f1()  { return(_Ask + 1.0/(1.0+(double)rand())); }
   double            f2()  { return(_Bid + 1.0/(1.0+(double)rand())); }
   double            f3()  { return(_Ask/_Bid + 1.0/(1.0+(double)rand())); }
public:
   void              Init() {_Ask = 1.0 + 1.0 / (1.0 + (double)rand());
                             _Bid = 1.0 + 1.0 / (1.0 + (double)rand());}
   double            calc(){return(f1() + f2() + f3()); }
};
//+------------------------------------------------------------------+
class B
{
private:
   double            f1(const MqlTick &t)  { return(t.ask + 1.0/(1.0+(double)rand())); }
   double            f2(const MqlTick &t)  { return(t.bid + 1.0/(1.0+(double)rand())); }
   double            f3(const MqlTick &t)  { return(t.ask/t.bid + 1.0/(1.0+(double)rand())); }
public:
   double            calc(const MqlTick &tick){ return(f1(tick) + f2(tick) + f3(tick)); }
};
//+------------------------------------------------------------------+
void OnStart()
{
   A a;
   B b;
   MqlTick rnd_tick;
   for(int i=0; i<5; i++)
   {
      SpeedTest(TST_COUNT, "class A : ",
               a.Init();
               double res = a.calc();
      );
   
      SpeedTest(TST_COUNT, "class B : ",
               rnd_tick.ask = 1.0 + 1.0 / (1.0 + (double)rand());
               rnd_tick.bid = 1.0 + 1.0 / (1.0 + (double)rand());
               double res = b.calc(rnd_tick);
      );
   }
}

Et maintenant une question : qu'est-ce qui est le plus pratique pour vous ? Bien sûr, vous pouvez faire glisser une chaîne de liens à travers les paramètres de la méthode, ou vous pouvez le faire gentiment. Comparez vous-même les vitesses)))

 
Vladimir Simakov:

Mais vous avez pris un opérateur d'affectation absolument inutile (2 pcs.), et ainsi créé un code sciemment sous-optimal)))))

Ce n'était pas moi !

C'est le centre de connaissances IBM !https://www.ibm.com/support/knowledgecenter/ru/ssw_aix_72/performance/coding_style_best_perf.html



Les conditions sont les mêmes ici, à chaque tic vous devez appeler le gestionnaire de classe (ou super-classe, je ne sais pas)

et il appelle le reste des classes qui travaillent selon leurs stratégies

mais pour le bien de l'argument, la variante C gagne vraiment en vitesse, donc c'est le knoelege_center qui dit en quelque sorte la vérité.

 
Pavel Verveyko:

Je me demande s'il s'agit d'un bug ou d'une fonctionnalité)

Il existe une structure à l'intérieur de l'instance de la classe.

Je mets un point pour voir le contenu de la structure.
Mais il ne s'affiche que si je mets des crochets.
Bien que la structure soit dans une seule instance.

le problème est résolu si la classe n'est pas un élément du tableau.




voici le code pour "poking around".

essayer de le compiler, même avec des erreurs. Parfois, cela "réveille" l'éditeur

 
Igor Makanu:

Ce n'est pas moi !

c'est le centre de connaissances IBM !le prix actuel à toutes les méthodes



UPD :

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37985

Igor Makanu:

Ce n'est pas moi !

C'est le centre de connaissances IBM !https://www.ibm.com/support/knowledgecenter/ru/ssw_aix_72/performance/coding_style_best_perf.html



Les conditions sont les mêmes ici, à chaque tic vous devez appeler le gestionnaire de classe (ou superclasse, je ne sais pas)

et il appelle le reste des classes qui travaillent selon leurs stratégies

mais pour l'essentiel - l'option C gagne vraiment en rapidité, c'est-à-dire que knoelege_center dit en quelque sorte la vérité.

Bien sûr qu'il gagne.) Mais pas parce qu'il est écrit de manière optimale, mais parce que les compilateurs sont devenus plus intelligents). Optimisation pure. Il n'y a pas d'affectation des valeurs Ask et Bid dans le release code)))) Mais lorsque vous aurez un peu moins de paramètres à traiter, et que la logique commerciale du projet sera un peu plus que l'ouverture d'une commande par indicateur, alors je comprendrai que vous en ayez assez de faire glisser une chaîne de liens à travers tout le projet)))). Et oui, je vous ai déjà parlé du péché de l'optimisation excessive. Croyez-moi, vous n'en avez pas besoin dans 98 % des cas.

 
Vladimir Simakov:

Et oui, je vous ai déjà parlé du péché de sur-optimisation. Croyez-moi, vous n'en avez pas besoin 98% du temps.

Je fais ... mais mon instinct me dit que je ne peux pas y arriver tant que je n'y arrive pas ))))

Ok, merci, il y a du bon sens dans ces recherches.

 
Igor Makanu:


UPD :

2020.07.25 19:03:37.210 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.25 19:04:15.201 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:04:53.188 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37984

2020.07.25 19:05:39.321 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46125

2020.07.25 19:06:17.313 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.25 19:06:55.306 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=37985

Essayez aussi de cette façon :

class D
{
   double f1(const double &a, const double &b)  { return(a + 1.0/(1.0+(double)rand())); }
   double f2(const double &a, const double &b)  { return(b + 1.0/(1.0+(double)rand())); }
   double f3(const double &a, const double &b)  { return(a/b + 1.0/(1.0+(double)rand())); }
   
public:
   double calc( const MqlTick& tick )
   {
      return f1( tick.ask, tick.bid ) + f2( tick.ask, tick.bid ) + f3( tick.ask, tick.bid );
   }
};
 
Koldun Zloy:

Essayez aussi de cette façon :

2020.07.26 09:39:21.350 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46157

2020.07.26 09:39:59.402 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38046

2020.07.26 09:40:37.455 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=38063

2020.07.26 09:41:15.485 class_global (EURUSD,H1) class D : : : boucles = 10000000000 ms=38031

2020.07.26 09:42:01.749 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46266

2020.07.26 09:42:39.754 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.26 09:43:17.753 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=38000

2020.07.26 09:43:55.743 class_global (EURUSD,H1) class D : : boucles = 10000000000 ms=37984

Mêmes valeurs, la vitesse de test est "flottante" pour une raison quelconque, mais le passage de paramètres dans les méthodes par le lien est toujours plus efficace.
Raison: