MQL5의 OOP에 대한 질문 - 페이지 68

 
Dmitry Fedoseev :

그리고 뭐? 또 다른 패치. 그것은 패턴의 지지자들이 그를 인식하지 못한 것뿐입니다. 분명히 정통도 아니고 정식도 아닙니다. 재귀는 왜 안되지? 또한 재귀는 함께가 아니라 건너 뜁니다.

Igor는 자신에게 주기가 두 개 있고 기적을 한 주기로 압축할 수 없다고 불평했습니다.
그래서 나는이 사이트를 예를 들어 기억했습니다. 사이클이 전혀 없어도 될 수 있습니다. 그리고 기적이 일어날 것이다
그래서 나는 생각하기 위해 옵션을 제안했습니다)) 사이클없이 들어갈 수 있습니다.
그리고 종교에 따르지 않는 누군가가 모든 사람의 일이라는 사실.

 
Roman :

Igor는 자신에게 주기가 두 개 있고 기적을 한 주기로 압축할 수 없다고 불평했습니다.

나는 불평하지 않았지만 프로그래머의 비밀을 알아 냈습니다 :)

나는 그것을 할 수 있고, 나는 루프를 감쌀 수 있고 재귀 (교체) 할 수 있습니다. 그것은 좋은 생각이 될 것입니다 :)

로만 :

그리고 종교에 따르지 않는 누군가가 모든 사람의 일이라는 사실.

그것은 종교에 관한 것이 아니라 잘 정립된 프로그래밍 기술이 있다는 것을 이해하는 것입니다. 이러한 기술이 대다수에 의해 사용된다면 속도 면에서 효율적이고, 코드 가독성 면에서 효율적이고, 추가 지원에서 효율적이고, 재사용 면에서 효율적입니다. ..

그리고 종교? IMHO, 프로그래밍의 노하우는 일반적으로 재료(또는 정보)의 소유가 아니라 이러한 "갈퀴"를 자체 혁신으로 배포합니다.

 
Igor Makanu :

나는 불평하지 않았지만 프로그래머의 비밀을 알아 냈습니다 :)

나는 그것을 할 수 있고 루프를 감쌀 수 있고 재귀 (교체) 할 수 있습니다. 좋은 생각이 될 것입니다 :)

그것은 종교에 관한 것이 아니라 잘 정립된 프로그래밍 기술이 있다는 것을 이해하는 것입니다. 이러한 기술이 대다수에 의해 사용된다면 속도 면에서 효율적이고, 코드 가독성 면에서 효율적이고, 추가 지원에서 효율적이고, 재사용 면에서 효율적입니다. ..

그리고 종교? IMHO, 프로그래밍의 노하우는 일반적으로 재료(또는 정보)의 소유가 아니라 이러한 "갈퀴"를 자체 혁신으로 배포합니다.

예제 중 하나는 예제가 메타프로그래밍 패턴을 사용한다고 언급합니다.
템플릿을 사용하면 작업에 적합하다면 컴파일 타임에 계산을 수행하는 프로그램을 작성할 수 있습니다.
이러한 프로그램을 템플릿 메타 프로그램이라고 합니다.
터미널이 MetaTrader라고 불리는 것은 헛된 것이 아닙니다.
;))

 
Igor Makanu :

나는 불평하지 않았지만 프로그래머의 비밀을 알아 냈습니다 :)

나는 그것을 할 수 있고 루프를 감쌀 수 있고 재귀 (교체) 할 수 있습니다. 좋은 생각이 될 것입니다 :)

그것은 종교에 관한 것이 아니라 잘 정립된 프로그래밍 기술이 있다는 것을 이해하는 것입니다. 이러한 기술이 대다수에 의해 사용된다면 속도 면에서 효율적이고, 코드 가독성 면에서 효율적이고, 추가 지원에서 효율적이고, 재사용 면에서 효율적입니다. ..

그리고 종교? IMHO, 프로그래밍의 노하우는 일반적으로 재료(또는 정보)의 소유가 아니라 이러한 "갈퀴"를 자체 혁신으로 배포합니다.

Igor는 아침에 저항할 수 없었고 무릎을 꿇고 사이클이 없는 방법을 호출했습니다. 글쎄, 그것은 정말 편리합니다. *주의, SB 사용 :))

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

그리고 뭐? 또 다른 패치. 그것은 패턴의 지지자들이 그를 인식하지 못한 것뿐입니다. 분명히 정통도 아니고 정식도 아닙니다. 재귀는 왜 안되지? 또한 재귀는 함께가 아니라 건너 뜁니다.

이것을 "루프 언롤링"이라고 하며 OO 없이 템플릿은 컴파일러에 의해 수행됩니다(적어도 그래야 합니다).

중간 코드(어셈블러에서)를 살펴보면 루프 대신 한 행에 N 연산만 있을 것입니다.

 
의외의 결과를 얻었습니다.
 #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 :
의외의 결과를 얻었습니다.


sizeof를 통해 구조의 크기는 얼마입니까? 그렇지 않으면 컴퓨터에 있지 않습니까?
 
Vladimir Simakov :
sizeof를 통해 구조의 크기는 얼마입니까? 그렇지 않으면 컴퓨터에 있지 않습니까?
        : sizeof (STRUCT1) = 20
        : sizeof (STRUCT2) = 16

단순 구조의 크기가 클수록 작업 속도가 느려집니다.

 
fxsaber :

단순 구조의 크기가 클수록 작업 속도가 느려집니다.

첫 번째 구조를 {int;int;double[2]}로 만듭니다.
 
Vladimir Simakov :
첫 번째 구조를 {int;int;double[2]}로 만듭니다.
         Alert : Time[Test6.mq5 285 : Func(Array1)] = 378 ms.
         Alert : Time[Test6.mq5 286 : Func(Array2)] = 156 ms.
정렬은 불가능합니다. 바로 확인했습니다.