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

 
Igor Makanu:

少し作り直しました

(マクロは使わないほうがいい)

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count;_i++){EX;} \
                                              printf("%s: loops=%llu ms=%llu",msg,count,GetMicrosecondCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
{
   ulong sum = 0;
   uint in01A = (uint)rand();
   uint in01B = (uint)rand();
   uint in02A = (uint)rand();
   uint in02B = (uint)rand();
   uint in03A = (uint)rand();
   uint in03B = (uint)rand();
   uint in04A = (uint)rand();
   uint in04B = (uint)rand();
   uint in05A = (uint)rand();
   uint in05B = (uint)rand();
   uint param[5];
   SpeedTest(22, "tst 1 : ",
   {
      sum += in01A << (sizeof(ushort) * 8) | in01B;
      sum += in02A << (sizeof(ushort) * 8) | in02B;
      sum += in03A << (sizeof(ushort) * 8) | in03B;
      sum += in04A << (sizeof(ushort) * 8) | in04B;
      sum += in05A << (sizeof(ushort) * 8) | in05B;
   //   for(int i = 0; i < 5; i++) sum += param[i];
   });
   Print(sum);
   }
//--  

   ulong sum = 0;
   ushort in00 = (ushort)rand();
   ushort in01 = (ushort)rand();
   ushort in02 = (ushort)rand();
   ushort in03 = (ushort)rand();
   ushort in04 = (ushort)rand();
   ushort in05 = (ushort)rand();
   ushort in06 = (ushort)rand();
   ushort in07 = (ushort)rand();
   ushort in08 = (ushort)rand();
   ushort in09 = (ushort)rand(); 
   sum = 0;
   union ushortTouint
   {
      uint param[5];
      ushort in[10];
   }U;
      ushortTouint u;
   SpeedTest(22, "tst 2 : ",
   { 
      u.in[0] = in00;
      u.in[1] = in01;
      sum +=u.param[0];
      u.in[2] = in02;
      u.in[3] = in03;
      sum +=u.param[1];
      u.in[4] = in04;
      u.in[5] = in05;
      sum +=u.param[2];
      u.in[6] = in06;
      u.in[7] = in07;
      sum +=u.param[3];
      u.in[8] = in08;
      u.in[9] = in09;
      sum +=u.param[4];
    //  Comment(121);
   //  for(int i = 0; i < 5; i++) sum += u.param[i];
   });
Print(sum);
}
 
Alexandr Andreev:

少し作り直しました

(だからマクロは使わない方がいい;)

テスト時には、オプティマイザが空のループを投げ出さないように、できるだけコードを混乱させます。

ある

 //  for(int i = 0; i < 5; i++) sum += u.param[i];

MQL実行の最適化は、計算された値が使用されないため、最初のループを事前に終了させることができます。したがって、結果を伴うSpeedTest()の後に何かが行われる必要があります - このループ

コメントアウトされたループで確認したところ、捨てられませんでしたが、他のテストではクラッシュする可能性があります。


マクロは好みの問題で、私は何度もテストしてうまくいっています。



UPD: 最新のコンパイラがどのように動作するかについて書かれた記事を見つけました。

https://habr.com/ru/post/431688/

https://habr.com/ru/post/47878/

 

コードはハンドルのiRSIの値を与え、tpは 常に10だけですが、価格とグラフも変化します。

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)です。


ビルド2652

Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
  • www.mql5.com
Все предопределенные периоды графиков имеют уникальные идентификаторы. Идентификатор PERIOD_CURRENT означает текущий период графика, на котором запущена mql5-программа.
 
Aleksei Skrypnev:

コードはハンドルのiRSIの値を与え、tpは 常に10だけですが、価格とグラフも変化します。

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)です。


ビルド2652

インジケーターハンドルを手にしたあなたは、それが10

次に、右のバーの値を取得する必要があります

//--- создадим хэндл индикатора
   if(type==Call_iRSI)
      handle=iRSI(name,period,ma_period,applied_price);

//--- индикаторный буфер
double  rsi_buffer[];

//--- заполняем часть массива iRSIBuffer значениями из индикаторного буфера под индексом 0
   if(CopyBuffer(ind_handle,0,0,amount,rsi_buffer)<0)
     {
      //--- если копирование не удалось, сообщим код ошибки
      PrintFormat("Не удалось скопировать данные из индикатора iRSI, код ошибки %d",GetLastError());
      //--- завершим с нулевым результатом - это означает, что индикатор будет считаться нерассчитанным
      return(false);
     }

ヘルプを 読むか、フォーラムで回答を検索してください。

Документация по MQL5: Технические индикаторы / iRSI
Документация по MQL5: Технические индикаторы / iRSI
  • www.mql5.com
//|                                                    Demo_iRSI.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iRSI;               ...
 
Vitaly Muzichenko:

インジケーターハンドルを手にしたあなたは、それが10

次に、右のバーの値を取得する必要があります

ヘルプを 読むか、フォーラムで回答を検索してください。

了解です。緩衝材を研究します。不思議ですね、すべてそのまま動くはずのような気がしていたのですが、もしかしたらmql4と混同していたのかもしれませんね。

不思議なのは、ググってもmql5でインジケーターのデータを取得するところが見つからなかったことです。


あはは、私が理解したようにあなたの例によると、インジケータRSIの値は、最終的に以下の形式の変数にあります。

rsi_buffer[0] 
 
Igor Makanu:

をチェックしました。

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : loops=100000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : loops=100000000 ms=10862287

この差が有意でなければ、テストの順番を逆にすれば、結果は逆になる可能性が高い。

ノットクリティカル

この関数は他のコマンドよりはるかに多くのリソースを消費するため、rand()をテストに含めることはほとんど正しくありません。
この方が正しいテストになると思うのですが。

#define  Num 1000000
#define  SpeedTest(msg,s,EX)  {ulong mss=GetMicrosecondCount(); EX \
                                    mss=GetMicrosecondCount()-mss;\
                                    printf("%-22s%llu µs; Сумма - %llu",msg,mss,s);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong sum = 0;
   ushort in[];
   ArrayResize(in,Num*2);
   for (int i=0; i<Num*2; i++) in[i] = (ushort)rand();
   SpeedTest("test binary shift : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      sum+=in[i]<<(sizeof(ushort)*8) | in[i+1];
   });
//--   
   sum = 0;
   union ushortTouint
   {
      uint param;
      ushort in[2];
   } u;
   SpeedTest("test union : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      u.in[0]=in[i+1];
      u.in[1]=in[i];
      sum+=u.param;
   });
}

結果

2020.10.15 17:14:03.168 TestMakanu (USDCAD,M1)  test binary shift :   1384 µs; Сумма - 1074434582054198
2020.10.15 17:14:03.169 TestMakanu (USDCAD,M1)  test union :          1209 µs; Сумма - 1074434582054198
2020.10.15 17:14:19.370 TestMakanu (USDCAD,M1)  test binary shift :   1891 µs; Сумма - 1073924616844949
2020.10.15 17:14:19.371 TestMakanu (USDCAD,M1)  test union :          1289 µs; Сумма - 1073924616844949
2020.10.15 17:14:20.949 TestMakanu (USDCAD,M1)  test binary shift :   1342 µs; Сумма - 1073194788831653
2020.10.15 17:14:20.950 TestMakanu (USDCAD,M1)  test union :          1178 µs; Сумма - 1073194788831653
2020.10.15 17:14:27.141 TestMakanu (USDCAD,M1)  test binary shift :   1365 µs; Сумма - 1075017290553168
2020.10.15 17:14:27.142 TestMakanu (USDCAD,M1)  test union :          1362 µs; Сумма - 1075017290553168
2020.10.15 17:14:28.202 TestMakanu (USDCAD,M1)  test binary shift :   1354 µs; Сумма - 1075051817914563
2020.10.15 17:14:28.203 TestMakanu (USDCAD,M1)  test union :          1105 µs; Сумма - 1075051817914563

幸いなことに、結局は乗せる馬を間違えてしまったのだが。労働組合はもう少し早いです。より便利で、より読みやすいコードになります。

 
Nikolai Semko:

というのも、この関数は他のコマンドに比べて桁違いにリソースを消費するためです。

一顧だにしない

rand() の実行時間は一定で、一般的なC++関数である可能性が高い。"rand c++ source code "でググってみてください。

は初期化する必要がありますが、定数で初期化すると最適化に遭遇する可能性があります。

一般に、rand()が嫌われるのは理解できない。

というような初期化も可能です。

void OnStart()
{
   for(int i=0;i<20;i++) Print(Myvalue());

}
//+------------------------------------------------------------------+
int Myvalue()
{
   const static int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
   static int cnt = ArraySize(arr);
   if(--cnt < 0) cnt = ArraySize(arr) - 1;
   return(arr[cnt]);
}

は速いだろう。


は、あなたのスクリプトを実行しましたが、正しくありません。

主な時間は、コードをキャッシュにロードし、プロセッサにロードすることです

を追加し、システムタイマーの 離散性

うーんほぼ乱数

100500回くらいテストしてください。

 
Nikolai Semko:

rand()は他のコマンドに比べ、一桁多いリソースを消費するため、テストに含めることは正しくないと思われます。
この方が正しいテストになると思うのですが。

結果

幸いなことに、私はまだ間違った馬に賭けたままです。労働組合はもう少し早いです。より便利で、より読みやすいコードになります。


一度だけ、しかも初当選の距離で、(最初の方式でショートから何かの変換ラインを外したような)。

 
Igor Makanu:

一顧だにしない

rand() の実行時間は一定で、一般的なC++関数である可能性が高い。"rand c++ source code "でググってみてください。

は初期化する必要がありますが、定数で初期化すると最適化に遭遇する可能性があります。

一般に、rand()が嫌われるのは理解できない。

をバリアントとして、このようなもので初期化します。

はやいもので

要は、余計なものを排除して、測るべきものをきっちり測ればいいということです。

 
Alexandr Andreev:

ポイントは、余分なものがなく、必要なものを正確に測定することでした

ノー

繰り返されるコード断片があれば、最適化テストが行われるのです

rand()の実行時間にはどんな違いがあるのでしょうか?

テスト時間の2/3を実行させ、rand()の時間が一定であることが重要です。

MQLコードは、システムのMQL-functionsを使用するのですよね?- 完璧なコードをテストすることに何の意味があるのでしょうか?