Preguntas sobre POO en MQL5 - página 68

 
Dmitry Fedoseev:

¿Por qué? Otro patrón. Salvo que los adeptos a los patrones no lo reconocían, aparentemente no ortodoxos, no canónicos ¿Por qué no la recursividad? También la recursión, sólo que no a lo largo, sino a lo ancho.

Igor simplemente se quejó de que tiene dos ciclos y no puede meter el milagro en uno.
Entonces, me acordé de esta página web con un ejemplo, tal vez pueda prescindir de los bucles en absoluto. Y puede que ocurra un milagro ))
Y por eso sugerí esta variante para reflexionar )) tal vez funcione sin bucles.
Y el hecho de que alguien lo que no está de acuerdo con la religión, es una cuestión de cada uno.

 
Roman:

Igor sólo se quejaba de que tenía dos bucles y no podía meter un milagro en un bucle.

No me estaba quejando, estaba intentando aprender los secretos de los programadores :)

Puedo hacerlo, puedo envolver (reemplazar) un bucle con recursividad - simplemente tendría sentido :)

Romano:

Lo que no es religioso es asunto de todos.

No se trata de religión, sino de entender que hay prácticas de programación bien establecidas y que si la mayoría de la gente utiliza estas prácticas, significa que son eficaces: eficaces en términos de velocidad, eficaces en términos de legibilidad del código, eficaces en términos de mantenimiento posterior, eficaces en términos de reutilización...

y la religión... en mi opinión, el saber hacer en la programación suele consistir en no poseer el material (o la información) y luego difundir estos "rastrillos" como si fueran una innovación propia

 
Igor Makanu:

No me estaba quejando, estaba intentando aprender los secretos de los programadores :)

Puedo hacerlo, también puedo usar la recursividad, si sirve de algo :)

No se trata de religión, sino de la idea de que hay prácticas de programación bien establecidas y si la mayoría de la gente las utiliza, significa que son eficientes: eficientes en términos de velocidad, eficientes en términos de legibilidad del código, eficientes en términos de mantenimiento posterior, eficientes en términos de reutilización...

Y la religión... en mi opinión, el saber hacer en la programación suele consistir en no poseer el material (o la información) y luego difundir esos "rastrillos" como innovación propia

Un ejemplo menciona que el ejemplo utiliza un patrón de metaprogramación.
Utilizando plantillas, es posible escribir programas que realicen cálculos en tiempo de compilación, siempre y cuando se adapten a la tarea.
Tales programas se denominan metaprogramas de plantilla.
El terminal se llama MetaTrader por una razón.
;))

 
Igor Makanu:

No me estaba quejando, estaba intentando aprender los secretos de los programadores :)

Puedo hacerlo, también puedo usar la recursividad, si sirve de algo :)

No se trata de religión, sino de la idea de que hay prácticas de programación bien establecidas y si la mayoría de la gente las utiliza, significa que son eficientes: eficientes en términos de velocidad, eficientes en términos de legibilidad del código, eficientes en términos de mantenimiento posterior, eficientes en términos de reutilización...

¿Y la religión? imho, el know-how en la programación, por lo general no es poseer el material (o la información) y luego la difusión de estos "rastrillos" como su propia innovación

Igor, esta mañana no he podido resistirme y he dibujado en mi rodilla una llamada de cualquier método sin bucles. Por si acaso, puede resultar muy útil. *Cuidado, SB utilizado :))

#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:

¿Por qué? Otro patrón. Salvo que los adeptos a los patrones no lo reconocían, aparentemente no ortodoxos, no canónicos ¿Por qué no la recursividad? También es recursividad, sólo que no longitudinalmente, sino transversalmente.

Se llama "loop unrolling" y lo hace el compilador sin ningún tipo de OO y plantillas (al menos así debería ser).

Si miras en el código intermedio (ensamblador), sólo hay N operaciones seguidas en lugar de un bucle.

 
Obtuve un resultado inesperado.
#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:
Obtuve un resultado inesperado.


¿Cuáles son lasdimensiones de las estructuras mediante sizeof, porque no estoy en el ordenador?
 
Vladimir Simakov:
¿Cuál es el tamaño de las estructuras a través de sizeof, porque no estoy en la computadora?
        : sizeof(STRUCT1) = 20
        : sizeof(STRUCT2) = 16

Cuanto mayor sea el tamaño de la estructura simple, más lento será su manejo.

 
fxsaber:

Cuanto mayor sea el tamaño de la estructura simple, más lento será su manejo.

hacer la primera estructura {int;int;double[2]}
 
Vladimir Simakov:
hacer la primera estructura {int;int;double[2]}
        Alert: Time[Test6.mq5 285: Func(Array1)] = 378 ms.
        Alert: Time[Test6.mq5 286: Func(Array2)] = 156 ms.
La alineación no tiene nada que ver. Lo comprobé enseguida.