Questions on OOP in MQL5 - page 68

 
Dmitry Fedoseev:

Why? Another pattern. Except that the adherents of the patterns did not recognise it, apparently not orthodox, not canonical. Why not recursion? Also recursion, only not along, but across.

Igor simply complained that he has two cycles and cannot cram the miracle into one.
So, I remembered this web site with an example, maybe I can do without loops at all. And a miracle may happen ))
And so I suggested this variant to think over )) maybe it will work without loops.
And the fact that someone what is not according to religion, it's a matter of each.

 
Roman:

Igor was just complaining that he got two loops and could not cram a miracle into one loop.

I wasn't complaining, I was trying to learn programmers' secrets :)

I can do it, I can wrap (replace) a loop with recursion - if it would help :)

Roman:

What's not religious is everybody's business.

It's not about religion but understanding that there are well-established programming practices and if most people use these practices, it means that they are effective - effective in terms of speed, effective in terms of code readability, effective in terms of further maintenance, effective in terms of reuse...

and religion? imho, know-how in programming is usually about not owning the material (or information) and then disseminating these "rakes" as your own innovation

 
Igor Makanu:

I wasn't complaining, I was trying to learn the programmers' secrets :)

I can do it, I can also use recursion, if it would help :)

It's not about religion but the idea that there are well-established programming practices and if most people use them, it means that they are efficient - efficient in terms of speed, efficient in terms of code readability, efficient in terms of further maintenance, efficient in terms of reuse...

And religion? imho, know-how in programming is usually about not owning the material (or information) and then spreading these "rakes" as your own innovation

One example mentions that the example uses a metaprogramming pattern.
Using templates, it is possible to write programs that perform computations at compile time, as long as it suits the task.
Such programs are called template metaprograms.
The terminal is called MetaTrader for a reason.
;))

 
Igor Makanu:

I wasn't complaining, I was trying to learn the programmers' secrets :)

I can do it, I can also use recursion, if it would help :)

It's not about religion but the idea that there are well-established programming practices and if most people use them, it means that they are efficient - efficient in terms of speed, efficient in terms of code readability, efficient in terms of further maintenance, efficient in terms of reuse...

And religion? imho, know-how in programming, usually it's not owning the material (or information) and then spreading these "rakes" as your own innovation

Igor, I couldn't resist this morning and drew on my knee a call of any methods without loops. Just in case it may really come in handy. *Cautiously, SB used :))

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

Why? Another pattern. Except that the adherents of the patterns did not recognise it, apparently not orthodox, not canonical. Why not recursion? It's also recursion, only not longitudinally, but transversely.

It's called "loop unrolling" and is done by the compiler without any OO and templates (at least it should be).

If you look into the intermediate code (assembler), there are just N operations in a row instead of a loop.

 
Got an unexpected result.
#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:
Got an unexpected result.


What are thedimensions of the structures via sizeof, because I'm not at the computer?
 
Vladimir Simakov:
What is the size of structures via sizeof, because I'm not at the comp?
        : sizeof(STRUCT1) = 20
        : sizeof(STRUCT2) = 16

The larger the size of the simple structure, the slower it is handled.

 
fxsaber:

The larger the size of the simple structure, the slower it is handled.

make the first structure {int;int;double[2]}
 
Vladimir Simakov:
make the first structure {int;int;double[2]}
        Alert: Time[Test6.mq5 285: Func(Array1)] = 378 ms.
        Alert: Time[Test6.mq5 286: Func(Array2)] = 156 ms.
Alignment has nothing to do with it. I checked that right away.
Reason: