2017年2月21日火曜日

[MT4プログラム]小ネタ、どうしようもなく遅いCObjectArrayを少しでも高速化2

[MT4プログラム]小ネタ、どうしようもなく遅いCObjectArrayを少しでも高速化
http://mt4program.blogspot.jp/2017/02/mt4cobjectarray.html

の続きです。
ループのたびにチェック処理が入ると遅くなるため、チェック不要なことがはっきりしているのなら、チェックなんてやめてしまえばいいというのが前回の趣旨でした。

そもそもMQLには配列ムーブはありませんが、配列コピーなら存在します。
元の配列がそれほど大きくないことがあらかじめわかっているのであれば、バッファ用の配列を用意して、そこにいったんコピー後、一つずらして元に戻すという処理をおこなうともしかしたら早くなるかもしれません。
 MQLが〇〇で、内部でForループでコピーしているような、〇〇だと効果はないどころか逆効果になりますが・・・。果たして結果は!(〇〇は自己規制w)

修正前コード
//+------------------------------------------------------------------+
//| Inserting an element in the specified position                   |
//+------------------------------------------------------------------+
bool CCustomArrayObj::Insert(CObject *element,const int pos)
  {
//--- check
   if(pos<0 || !CheckPointer(element))
      return(false);
//--- check/reserve elements of array
   if(!Reserve(1))
      return(false);
//--- insert
   m_data_total++;
   if(pos < m_data_total - 1)
   {
      //--- copy from left to right
      //修正箇所
      int total = m_data_total - pos - 1;
      for(int i = total - 1; i >= 0; i--)
      {
         m_data[pos + i + 1] = m_data[pos + i];
      }
//      MemMove(pos+1,pos,m_data_total - pos - 1);
      m_data[pos]=element;
   }
   else
      m_data[m_data_total-1]=element;
   m_sort_mode=-1;
//--- successful
   return(true);
  }

修正後コード
//+------------------------------------------------------------------+
//| Inserting an element in the specified position                   |
//+------------------------------------------------------------------+
bool CCustomArrayObj::Insert(CObject *element,const int pos)
  {
//--- check
   if(pos<0 || !CheckPointer(element))
      return(false);
//--- check/reserve elements of array
   if(!Reserve(1))
      return(false);
//--- insert
   m_data_total++;
   if(pos < m_data_total - 1)
   {
      //--- copy from left to right
      //修正箇所
      int total = m_data_total - pos - 1;
      CObject *destArray[];
      ArrayResize(destArray, total);
      ArrayCopy(destArray, m_data, 0, pos, total);
      ArrayCopy(m_data, destArray, pos + 1, 0, total);

      m_data[pos]=element;
   }
   else
      m_data[m_data_total-1]=element;
   m_sort_mode=-1;
//--- successful
   return(true);
  }

■修正前

■修正後

おお。ちゃんと早くなりました。
内部はちゃんとメモリのブロックコピーで実装されているようで安心しました。

この手法は、コピー対象のバッファサイズが増えると一時的なメモリ量が増えるという問題もあります。余計なスワップが発生して処理が遅くなる可能性があるためそれはそれで注意です。

ハーモニックパターン検出インジケータV9ですが、このような、小手先の高速化では限界が近くなってきました・・。

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ FX テクニカルトレード派へ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。