Questions sur la POO dans MQL5 - page 68

 
Dmitry Fedoseev:

Pourquoi ? Un autre modèle. Sauf que les adeptes des modèles ne l'ont pas reconnu, apparemment pas orthodoxe, pas canonique. Pourquoi pas la récursion ? C'est aussi une récursion, mais pas le long, mais à travers.

Igor s'est simplement plaint d'avoir deux cycles et de ne pas pouvoir faire tenir le miracle en un seul.
Alors, je me suis souvenu de ce site web avec un exemple, peut-être que je peux me passer de boucles du tout. Et un miracle peut se produire ;))
Et donc j'ai suggéré cette variante pour réfléchir :) peut-être cela fonctionnera-t-il sans boucles.
Et le fait que quelqu'un quoi n'est pas selon la religion, c'est une question de chacun.

 
Roman:

Igor se plaignait juste d'avoir deux boucles et de ne pas pouvoir faire de miracle en une seule.

Je ne me plaignais pas, j'essayais d'apprendre les secrets des programmeurs :)

Je peux le faire, je peux envelopper (remplacer) une boucle par une récursion - si cela peut aider :)

Romain:

Ce qui n'est pas religieux est l'affaire de tous.

Il ne s'agit pas de religion, mais de comprendre qu'il existe des pratiques de programmation bien établies et que si la plupart des gens utilisent ces pratiques, cela signifie qu'elles sont efficaces - efficaces en termes de vitesse, efficaces en termes de lisibilité du code, efficaces en termes de maintenance ultérieure, efficaces en termes de réutilisation...

et la religion ? à mon avis, le savoir-faire en matière de programmation consiste généralement à ne pas posséder le matériel (ou l'information), puis à diffuser ces "râteaux" comme une innovation propre.

 
Igor Makanu:

Je ne me plaignais pas, j'essayais d'apprendre les secrets des programmeurs :)

Je peux le faire, je peux aussi utiliser la récursion, si cela peut aider :)

Il ne s'agit pas de religion, mais de l'idée qu'il existe des pratiques de programmation bien établies et que si la plupart des gens les utilisent, cela signifie qu'elles sont efficaces - efficaces en termes de vitesse, efficaces en termes de lisibilité du code, efficaces en termes de maintenance ultérieure, efficaces en termes de réutilisation...

Et la religion ? À mon avis, le savoir-faire en programmation consiste généralement à ne pas posséder le matériel (ou l'information), puis à diffuser ces "râteaux" en tant que propre innovation.

Un exemple mentionne que l'exemple utilise un modèle de métaprogrammation.
En utilisant des modèles, il est possible d'écrire des programmes qui effectuent des calculs au moment de la compilation, pour autant que cela convienne à la tâche.
De tels programmes sont appelés métaprogrammes modèles.
Le terminal ne s'appelle pas MetaTrader pour rien.
;))

 
Igor Makanu:

Je ne me plaignais pas, j'essayais d'apprendre les secrets des programmeurs :)

Je peux le faire, je peux aussi utiliser la récursion, si cela peut aider :)

Il ne s'agit pas de religion, mais de l'idée qu'il existe des pratiques de programmation bien établies et que si la plupart des gens les utilisent, cela signifie qu'elles sont efficaces - efficaces en termes de vitesse, efficaces en termes de lisibilité du code, efficaces en termes de maintenance ultérieure, efficaces en termes de réutilisation...

Et la religion ? à mon avis, le savoir-faire en matière de programmation, ce n'est généralement pas posséder le matériel (ou l'information) et ensuite diffuser ces "râteaux" comme sa propre innovation.

Igor, je n'ai pas pu résister ce matin et j'ai dessiné sur mon genou un appel de toutes les méthodes sans boucles. Juste au cas où cela pourrait s'avérer utile. *Cautièrement, SB utilisé :))

#include <Arrays\List.mqh>
//+------------------------------------------------------------------+
class base : public CObject
  {
public:
   virtual void      HighPriorityTask() {}
   virtual void      Task() {}
  };
//+------------------------------------------------------------------+
class A: public base
  {
private:
   static            A*lastnode;
   static            A*rootnode;
   static int        ID_counter;

public:
   int               ID;
                     A()
     {
      Prev((CObject*)lastnode);
      A*self = GetPointer(this);
      if(lastnode)
         lastnode.Next(self);
      lastnode=self;
      if(rootnode==NULL)
         rootnode=self;
      ID=ID_counter++;
     }
   static  A*        GetRoot() {return rootnode;}

   virtual void      HighPriorityTask() { Print(__FUNCSIG__," ID=",ID); A* next=(A*)Next(); if(next!=NULL) next.HighPriorityTask(); }
  };
A* A::rootnode=NULL;
A* A::lastnode=NULL;
int A::ID_counter=0;
//+------------------------------------------------------------------+
class B: public base
  {
public:
   virtual void      Task() { Print(__FUNCSIG__); }
  };

//+------------------------------------------------------------------+
void OnStart()
  {
   base *obj[4];;
   obj[0] = new A;
   obj[1] = new A;
   obj[2] = new B;
   obj[3] = new B;
   A* arr[5];
   for(int i=0; i<5; i++)
     {
      arr[i]= new A();
     }
   if(A::GetRoot()!=NULL)
      A::GetRoot().HighPriorityTask();
   for(int i=ArraySize(obj)-1; i>=0; i--)
     {
      //obj[i].HighPriorityTask();
      obj[i].Task();
     }

   for(int i=ArraySize(obj)-1; i>=0; i--)
      delete obj[i];
   for(int i=0; i<5; i++)
     {
      delete arr[i];
     }
  }
//+------------------------------------------------------------------+
 
Dmitry Fedoseev:

Pourquoi ? Un autre modèle. Sauf que les adeptes des modèles ne l'ont pas reconnu, apparemment pas orthodoxe, pas canonique. Pourquoi pas la récursion ? C'est aussi une récursion, mais pas longitudinalement, mais transversalement.

C'est ce qu'on appelle le "loop unrolling" et il est effectué par le compilateur sans aucun OO ni modèle (du moins, il devrait l'être).

Si vous regardez dans le code intermédiaire (assembleur), il y a juste N opérations à la suite au lieu d'une boucle.

 
J'ai obtenu un résultat inattendu.
#include <fxsaber\Benchmark.mqh> // https://c.mql5.com/3/321/Benchmark.mqh

// Простая структура.
struct STRUCT1
{
  int i;  
  double j[2];
};

// Сложная структура.
struct STRUCT2
{
  int i;  
  string Str;
  
  STRUCT2() : Str("1234567 1234567")
  {
  }
};

template <typename T>
int Func( T &Array[] )
{  
  // Write
  for (int i = ArraySize(Array) - 1; i >= 0; i--)
    Array[i].i = i;

  int Sum = 0;
  
  // Read
  for (int i = ArraySize(Array) - 1; i >= 0; i--)
    Sum += Array[i].i;
    
  return(Sum + ArraySize(Array));    
}

void OnStart()
{
  STRUCT1 Array1[]; // Простая структура.
  STRUCT2 Array2[]; // Сложная структура.
  
  const int Amount = 5 e7;
  
  Print(_B(ArrayResize(Array1, Amount), 1));
  Print(_B(ArrayResize(Array2, Amount), 1));
    
  Print(_B(Func(Array1), 1)); // Чтение и запись простой структуры происходит в разы дольше,
  Print(_B(Func(Array2), 1)); // чем сложной.
}


        50000000
        Alert: Time[Test6.mq5 280: ArrayResize(Array2,Amount)] = 640 ms.
        50000000
        Alert: Time[Test6.mq5 282: Func(Array1)] = 440 ms.
        1333106752
        Alert: Time[Test6.mq5 283: Func(Array2)] = 156 ms.
        1333106752
 
fxsaber:
J'ai obtenu un résultat inattendu.


Quelles sont lesdimensions des structures via sizeof, car je ne suis pas devant l'ordinateur ?
 
Vladimir Simakov:
Quelle est la taille des structures via sizeof, car je ne suis pas à l'ordinateur ?
        : sizeof(STRUCT1) = 20
        : sizeof(STRUCT2) = 16

Plus la taille de la structure simple est grande, plus son traitement est lent.

 
fxsaber:

Plus la taille de la structure simple est grande, plus son traitement est lent.

faire la première structure {int;int;double[2]}
 
Vladimir Simakov:
faire la première structure {int;int;double[2]}
        Alert: Time[Test6.mq5 285: Func(Array1)] = 378 ms.
        Alert: Time[Test6.mq5 286: Func(Array2)] = 156 ms.
L'alignement n'a rien à voir avec cela. Je l'ai vérifié tout de suite.
Raison: