MQL5におけるOOPに関する質問 - ページ 68

 
Dmitry Fedoseev:

なぜ?もう一つのパターン。ただし、パターンの信奉者はそれを認めず、どうやら正統派ではなく、正典でもないようだ。 なぜ再帰性ではないのか?また、再帰性は、alongではなくacrossである。

イゴールは、「2つのサイクルがあるから、奇跡を1つに詰め込むことはできない」と訴えるだけだった。
そこで、このホームページの例を思い出したのですが、もしかしたら、ループが全くなくてもいけるかもしれませんね。そして、奇跡が起こるかもしれない ))
そして、私はこのバリエーションを提案し、熟考してもらいました )) もしかしたら、ループなしで動くかもしれません。
そして、誰かが何をするということは、宗教によるものではなく、それぞれの問題なのです。

 
Roman:

イゴールは、2つのループを得たのに、1つのループに奇跡を詰め込むことができなかったと文句を言っているだけだ。

文句を言ったのではなく、プログラマーの秘密を学ぼうとしたのです :)

ループを再帰で包む(置き換える)ことができるんですよ、それだけで意味があるんです :)

ローマン

無宗教のことは、みんなの問題だ。

それは宗教の問題ではなく、確立されたプログラミングのプラクティスがあり、多くの人がそれを使っているということは、それが効果的であるということです。

プログラミングのノウハウは、素材(情報)を所有しないこと、そして、その「熊手」を自分のイノベーションとして発信することだと思うのです。

 
Igor Makanu:

文句を言ったのではなく、プログラマーの秘密がわかったのです :)

私はそれを行うことができます、私はまた、再帰を使用することができます、それが役立つならば、)

それは宗教の問題ではなく、確立されたプログラミングのやり方があり、多くの人がそれを使うということは、それが効率的であるということだ、という考え方です。

プログラミングのノウハウは、素材(情報)を所有せず、その「熊手」を自分のイノベーションとして広めていくのが普通だと思うのですが、宗教はどうなんでしょう?

ある例では、メタプログラミングのパターンを使っていることに言及しています。

このようなプログラムをテンプレートメタプログラムという。テンプレートを用いると、コンパイル時に計算を行うプログラムを、そのタスクに合った形で書くことができる。
ターミナルがMetaTraderと呼ばれているのには理由があります。
;))

 
Igor Makanu:

文句を言ったのではなく、プログラマーの秘密を学ぼうとしたのです :)

私はそれを行うことができます、私はまた、それが役立つならば、再帰を使用することができます)

それは宗教の問題ではなく、確立されたプログラミングの手法があり、多くの人がそれを使うということは、それが効率的であるということだ、という考え方です。

そして、宗教?イミフ、プログラミングのノウハウ、通常、それは材料(または情報)を所有し、そしてこれらの「レイキ」を自分のイノベーションとして広めることではありません。

イゴール、今朝は我慢できず、膝の上にループのないあらゆるメソッドの呼び出しを描いてしまったよ。本当に便利かもしれないので、念のため。*注意: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.
アライメントは関係ない。すぐに確認しましたよ。