Questions sur la POO dans MQL5 - page 88

 
Igor Makanu:
mêmes valeurs, la vitesse du test "flotte" pour une raison quelconque, mais passer les paramètres dans les méthodes par référence est toujours plus efficace

Il y a aussi cette option :

class E
{
   double f1( double a, double b )  { return(a + 1.0/(1.0+(double)rand())); }
   double f2( double a, double b )  { return(b + 1.0/(1.0+(double)rand())); }
   double f3( double a, 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:

Il y a aussi cette option :

2020.07.26 10:10:52.254 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.26 10:11:30.261 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38000

2020.07.26 10:12:08.258 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=38000

2020.07.26 10:12:46.254 class_global (EURUSD,H1) class D : : : boucles = 10000000000 ms=38000

2020.07.26 10:13:24.279 class_global (EURUSD,H1) class E : : boucles = 10000000000 ms=38031

2020.07.26 10:14:10.484 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46203

2020.07.26 10:14:48.570 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38078

2020.07.26 10:15:26.737 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=38172

2020.07.26 10:16:04.734 class_global (EURUSD,H1) class D : : : boucles = 10000000000 ms=38000

2020.07.26 10:16:42.739 class_global (EURUSD,H1) class E : : boucles = 10000000000 ms=38000

2020.07.26 10:17:28.886 class_global (EURUSD,H1) class A : : boucles = 10000000000 ms=46141

2020.07.26 10:18:06.894 class_global (EURUSD,H1) class B : : boucles = 10000000000 ms=38015

2020.07.26 10:18:44.888 class_global (EURUSD,H1) class C : : boucles = 10000000000 ms=38000

2020.07.26 10:19:22.948 class_global (EURUSD,H1) class D : : : boucles = 10000000000 ms=38047

2020.07.26 10:20:00.983 class_global (EURUSD,H1) class E : : boucles = 10000000000 ms=38047

étrange, mais aucune différence

UPD : si je ne me trompe pas, j'ai cherché une erreur dans MT4 il y a des années - j'ai passé des arguments à une fonction NON par référence et ensuite j'ai changé (fait une erreur) un des arguments de la fonction dans le corps de la fonction. je pouvais changer un argument passé par référence, peut-être dans la variante E le compilateur passait tous les arguments par référence aussi.

 
Igor Makanu:
étrange, mais il n'y a pas de différence.

Il n'y a rien d'étrange à cela. double est de 8 octets, la référence est également de 8 octets. Mais la référence doit encore obtenir les 8 octets du numéro.

 
Koldun Zloy:

Il n'y a rien d'étrange à cela. double est de 8 octets, la référence est également de 8 octets. Mais le lien doit toujours obtenir 8 octets d'un nombre.

C'est logique, et les chiffres s'additionnent pour donner 8 à l'aller et 8 au retour ;))

mais le bus n'est pas de 8 bits dans un processeur ? il faut lire 8 octets = 64 bits par cycle d'horloge ?

 
Igor Makanu:

c'est logique, et les chiffres s'additionnent pour donner 8 à l'aller et 8 au retour ;))

Mais le bus n'est pas de 8 bits dans un processeur, est-il censé lire 8 octets = 64 bits par cycle d'horloge ?

Ce n'est pas aussi simple là-bas. La vitesse dépend à la fois de la mémoire dans laquelle se trouve l'objet et d'autres raisons.

Dans un programme réel, le résultat peut être très différent de celui d'un simple test.

En général, les classes et les structures sont transmises par référence.

Les types simples ne sont transmis par référence que si une valeur est retournée par le type en question.

 

J'ai été surpris de constater qu'il est possible d'accéder aux champs d'une structure même si cette structure est renvoyée comme résultat d'une fonction.

ce code fonctionne correctement (on remplit la structure dans la fonction, puis on copie le résultat de la fonction dans un tableau d'octets)

struct UcharArray
{
   uchar             byte[];
};
//+------------------------------------------------------------------+
UcharArray f()
{
   UcharArray result;
   for(uchar i = 0; i < 10; i++)
   {
      uchar tmp[1];
      tmp[0] = i;
      ArrayCopy(result.byte, tmp, ArraySize(result.byte));
   }
   return result;
}
//+------------------------------------------------------------------+
void OnStart()
{
   uchar arr[];
   for(int i = 0; i < 3; i++)
   {
      ArrayCopy(arr, f().byte, ArraySize(arr));
   }
   
   ArrayPrint(arr); // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

}
//+------------------------------------------------------------------+

il est pratique d'utiliser un tel accès au champ de la structure, ..... où peut-il y avoir des pièges - des bogues/erreurs ?

 
Igor Makanu:

J'ai été surpris de constater qu'il est possible d'accéder aux champs d'une structure même si cette structure est renvoyée comme résultat d'une fonction.

ce code fonctionne correctement (on remplit la structure dans la fonction, puis on copie le résultat de la fonction dans un tableau d'octets)

il est pratique d'utiliser un tel accès au champ de la structure, ..... où peut-il y avoir des pièges/bugs/erreurs ?

Ce genre de choses)) il n'y a pas de bogues.

 ArrayCopy(arr, (f()).byte, ArraySize(arr))

Donc, plus correctement, c'est de l'opéra (.)(.)

Je ne comprends pas non plus ce que la copie dans un tableau d'octets a à voir avec cela. Il s'agit juste d'accéder aux données de la structure retournée.
 
Alexandr Andreev:
Il s'agit simplement d'accéder aux données de la structure retournée.

oui, mais c'est déroutant que j'accède au champ d'octets sans variable intermédiaire, directement au résultat de f()

C'est pourquoi j'attends une prise.

f().byte
 
Igor Makanu:

oui, mais c'est déroutant que j'accède au champ d'octets sans variable intermédiaire, directement au résultat de la fonction f()

C'est pourquoi j'attends une prise.

il est stable depuis quelques années maintenant.

 
Alexandr Andreev:

est stable depuis quelques années maintenant.

OK, merci !