エラー、バグ、質問 - ページ 2676

 
Sergey Dzyublik:

MT5 (build 2347) ArrayResizeを使用して配列に要素を1つずつ追加する際に、あらかじめメモリが確保されている場合、なぜこのような大きなオーバーヘッドが発生するのでしょうか?

ArrayResizeによる内部予約アルゴリズムの改良をご検討ください。

例えば、クラスの場合、コンストラクタを呼び出すだけでなく、何らかの「リストへの内部登録」を行うことが想定される。
そして、ArrayResizeによる予約の枠内で、直接のメモリ確保とは別に、処理の最適化を図ることができるのです。
- 隣接して作成された要素からデータを取得する(例:仮想関数 テーブルへのポインタ)。
- まだ作成されていないクラスの「内部登録」のために、事前に実行またはスペースを確保する。

メッセージをありがとうございました。

ArrayResizeのコードは、empty(要素数に変化がない場合)に呼び出されないように保護されているため、関数コードは機能しません。

一方、要素数が実際に変わると、ArrayResize 関数のどちらか一方が起動し、配列に依存します。


提示されたコードのおかげで、ArrayResizeの一部分の複雑さをゼロにすることができました。
 
Ilyas:

端末のメモリ消費量を減らす方法を教えてください。EAを動かすときは、数百万ティックを要求しています。その上で計算をするので、もう必要ない。ティック関数で新鮮なティックを読み込むだけなので、隙間はありません。


この100万回の刻みのために、端末は500Mbのメモリを消費し、それを急いで解放することはないのです。もっと正確に言うと、単純に解放されないのです。Terminal のキャッシュを強制的にすべてクリアして、消費量を最小限に抑えることは可能ですか?VPSの場合、1端末あたり0.5GBは多すぎです。

 
fxsaber:

端末のメモリ消費量を減らす方法を教えてください。EAを動かすときは、数百万ティックを要求しています。その上で計算をするので、もう必要ない。ティック関数で新鮮なティックを読み込むだけなので、隙間はありません。


この100万回の刻みのために、端末は500Mbのメモリを消費し、それを急いで解放することはないのです。もっと正確に言うと、単純に解放されないのです。Terminal のキャッシュを強制的にすべてクリアして、消費量を最小限に抑えることは可能ですか?VPSの場合、1端末あたり0.5GBでは多すぎる。

ArrayFree

プログラムが複雑な動的環境でメモリを管理する必要がある場合、ArrayFree()関数により、不要になった動的配列が占有しているメモリを明示的かつ即時に解放することができます。

Документация по MQL5: Операции с массивами / ArrayFree
Документация по MQL5: Операции с массивами / ArrayFree
  • www.mql5.com
//| Класс диалога для работы с памятью                               | //| Освобождение памяти текущего массива                             | //| Попытка добавления памяти для текущего массива                   | //| Обработка событий                                                |...
 
Slava:

ArrayFree

もちろん無料です。端末自体がキャッシュに刻みを記憶しているので、運用中は必要ないんですけどね。

このダニは寒いときにもう一度上げたほうがいいんです。端末を「冷やす」仕組みが必要なんです。

 

こんにちは、テスターのCopyTicksとCopyTicksRangeが他のツールからデータを取得できない問題が発生しました...。チャートに追加すると、すべてが機能します。

ビルド2363(2361でも同じだった)

間違えてしまったのでしょうか?助けてください!ありがとうございました。

#property copyright "Copyright 2020, LittleBitTime"
#property link      "https://login.mql5.com/ru/users/LittleBitTime"
#property version   "1.00"

int OnInit() {
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) {
}

void OnTick() {
   MqlTick LastTick;
   if (SymbolInfoTick(Symbol(), LastTick)) {
      //Print("START");
      
      if (GetTicks("RTS-3.20", LastTick.time_msc) && GetTicks("RTS-6.20", LastTick.time_msc)) {
         Print("История загружена");
      } else {
         Print("Ошибка загрузки истории");
      }
      //Print("END");
   } else {
      Print("Ошибка получения последнего тика, для получения последнего известного времени");
   }
}

bool GetTicks(string symbol, ulong TimeEnd) {
   ulong TimeStartPeriod = TimeEnd-(60*1000);
   
   MqlTick ticks[];
   bool success = false; //флаг успешного выполнения копирования тиков
   uint start = GetTickCount(); //замерим время старта перед получением тиков
   
   int received = CopyTicksRange(symbol, ticks, COPY_TICKS_ALL, TimeStartPeriod, TimeEnd);
   if (received != -1) {
      //выведем информацию о количестве тиков и затраченном времени времени
      PrintFormat("%s: received %d ticks in %d ms", symbol, received, GetTickCount()-start);
      //если тиковая история синхронизирована, то код ошибки равен нулю
      if (GetLastError() == 0)
         success = true;
      else
         PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d", symbol, received, GetTickCount()-start, _LastError);
   }
   
   if (!success) {
      PrintFormat("Ошибкаp загрузки тиков! " + symbol);
      
      return false;
   }
   
   
   return true;
}
ファイル:
terminal.png  59 kb
tester.png  25 kb
tester_log.png  41 kb
 
LittleBitTime:

こんにちは、テスターのCopyTicksとCopyTicksRangeが他のツールからデータを取得できない問題が発生しました...。チャートに追加すると、すべてが機能します。

ビルド2363(2361でも同じだった)

間違えてしまったのでしょうか?助けてください!ありがとうございました。

CopyTicksがテスターでデータのアップロードを開始しない

まず、希望する機器のCopyRatesをリクエストしてください。1小節以上。その後、ポンピングとティックシーケンスの生成が 行われます。

その後、静かにリクエストを刻む

Основы тестирования в MetaTrader 5
Основы тестирования в MetaTrader 5
  • www.mql5.com
Идея автоматической торговли привлекательна тем, что торговый робот может без устали работать 24 часа в сутки и семь дней в неделю. Робот не знает усталости, сомнений и страха,  ему не ведомы психологические проблемы. Достаточно четко формализовать торговые правила и реализовать их в виде алгоритмов, и робот готов неустанно трудиться. Но прежде...
 
Ilyas:

メッセージをありがとうございました。
ArrayResizeのコードには、空の呼び出し(要素数に変化がない場合)に対する保護機能があるため、この関数コードは機能しません。
一方、要素数を実際に変更すると、配列に応じて ArrayResize 関数のどちらか一方が起動します。

提示されたコードのおかげで、ArrayResizeの1つの部分の複雑さをゼロにすることができました。

こんにちは、ありがとうございました。
論理的には予約メモリでArrayResizeより遅いはずなので、今までnew演算 子を使ったことがありません。
しかし、得られた結果には感心しました。逆にnew演算子を介したネイティブ配列の方が高速であることが判明したのです。

MT5 (ビルド 2363)です。

#define  K 1000
#define  M (1000 * K)

#define    SpeedTest(test_count,msg,EX)        {uint mss=GetTickCount(); ulong count=test_count;for(ulong ii=0;ii<count&&!_StopFlag;ii++){EX;} \
                                              printf("%-60s: loops=%i ms=%u",msg,count,GetTickCount()-mss);}
                                              
class A{
public:
   int data;
};


template<typename T>
void test1(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
      ArrayResize(class_array, array_size);
   }
   )
};

template<typename T>
void test2(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with reserved memory",
   {
      T class_array[];
      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 2; i <= array_size; i++){
         ArrayResize(class_array, i);
      }
   }
   )
};

template<typename T>
void test3(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with new operator",
   {
      T* class_array[];
      ArrayResize(class_array, array_size);
      for (int i = 0; i < array_size; ++i){
         class_array[i] = new T();
      }
      for (int i = 0; i < array_size; ++i){
         delete class_array[i];
      }
   }
   )
};


void OnStart()
{
  const int test_count = 1*K;
  const int array_size = 25*K;  
  
   printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
   test1<A>(test_count, array_size);              // Avg time: release( 730) / debug( 830)
   test2<A>(test_count, array_size);              // Avg time: release(1540) / debug(1720)
   test3<A>(test_count, array_size);              // Avg time: release(1200) / debug(1470)
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
}
  
 
Slava:

CopyTicksがテスターでデータのアップロードを開始しない

まず、希望する機器のCopyRatesをリクエストしてください。1小節以上。その後、ポンピングとティックシーケンスの生成が 行われます。

その後、静かにリクエストを刻む

ありがとうございました、助かりました。ドキュメントには載っていなかったのですが...。それとも、私が十分に見ていなかったのか?そこに書くのは悪いことではないでしょう :)
 
LittleBitTime:
ありがとうございました、助かりました。ドキュメントを探しても見つからず......。それとも私の検索が悪かったのか?そこに書くといいと思います :)

CopyRatesの ように自動アップロードができるようになると良い。

 

昨日、私のプロフィールの "古い "非アクティブなエージェントのリストをクリーンアップしました。

一日後、プロフィールにアクセスすると、エージェントのリストが削除されたエントリに復元されているのを確認しました。

また、エージェントの作成日および活動日を変更しました。

cloud.mql5.comで エージェントの統計情報を見た後、リストが復元されるという仮定(おそらく誤り)があります。