defineの専門家に質問 - ページ 5

 
Alexandr Andreev:

テストの完全なコードを教えてください

しかし、rand() についてもう一度議論する意味があるとは思えませんし、代わりに inc++ 変数に置き換えてください。

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}



//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

}


然り私のコードにエラーがあります、時間を秒単位で出力したいのですが、10倍になってしまいます、正しく1 000 000で割ったのですが、何が原因かわかる方教えてください

 
Igor Makanu:

しかし、rand() についてもう一度議論する意味があるとは思えませんし、代わりに inc++ 変数に置き換えてください。


然り私のコードに何らかのエラーがあります。時間を秒単位で出力したいのですが、10倍以上になって しまいます。

BOMBです。

これが、その逆であることを証明するあなたのコードです。

//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
}
 
Alexandr Andreev:

BOMB

以下は、その逆を証明するあなたのコードです。

チェックを入れ替えただけです。

 
Alexandr Andreev:

チェックを入れ替えただけ

2020.11.02 21:01:38.590 22222 (USDCHF,H1) cnt: loops = 1000 seconds=821.7159

2020.11.02 21:01:52.353 22222 (USDCHF,H1) ArraySize: loops = 1000 seconds=807.9415


このことから、ArraySizeは変数を使うよりも高速であることがわかります =))) テストが何か間違って いる
 
Roman:

どんなテスト? ))
あなた自身は、サイクル条件の両方のバリエーションを示しています。
Igorは上のコードもあげています。
ループ条件にArraySize()を入れて、可変サイズでのループのパフォーマンスを測定してください。

証明してくれ)

なぜなら、私のテストでは、それらは同じだからです

 
Alexandr Andreev:

チェックを入れ替えただけです。

ええ、そうしなければなりません。

今回は手抜きしすぎました。

テストを外部ループに巻き込み、以下のようにしました。

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=13.4910

 
Igor Makanu:

そうです、やらなければならないのです。

今回は手抜きしすぎました。

テストを外部ループで包むと、次のようになります。

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: loops = 1000 seconds=13.4910

今すぐループに入れ替え、驚きの声をあげよう

 
Alexandr Andreev:

今、ループの中でそれらを交換し、あなたは驚かれることでしょう

私は、コンパイラがその場でコードを最適化できることを知っているので、驚かない。

が、ネストされたループでは、やはり不必要にArraySize()を呼び出さない 方がいいというのがイミフです。

for(int i = ArraySize(arr)-1; i >=0 ; i--)

もちろん、それは時々不便かもしれないので、私は一時的な変数を介してループを行う - あなたのバージョン№2

信頼性が高く、何が起こるか理解できる。

 

まあIMHOに対しては何も言えませんけどね。

非常に大きなリプレイで、1回目と2回目の方法で勝敗がランダムになってしまった...。おそらく、現在のCPUキャッシュと全体の負荷に依存するようになったのでしょう。

私の質問は、ループについてではなく、関数がどのように展開されるかということでした。ちょうど、ArraySizeの例でした。

その結果

for (int i=0; i<ArraySIze(mas); i++) ==for (int i=0; i<size; i++)


しかし、2番目の部分に変数 sizeの初期 化を加えると、この変数を初期化して値と等しくする時間は、1番目のメソッドがリードすることになります。

 

ループの本体で配列のサイズを変更した場合、オンザフライの最適化は機能しない

ので、コードを変更します。

for(int loop=0; loop <5;loop++)
   {
   int cnt1 = ArrayResize(arr1, 100+loop);
   int cnt2 = ArrayResize(arr2, 200+loop);
   int cnt3 = ArrayResize(arr3, 300+loop);
   
   SpeedTest(3,"cnt",
.....

Alexandr Andreev:

の場合、最初の方法が優先されます。この変数を初期化して値と等しくする時間のために、高い繰り返しで初めて顕著になります。

ノーマーク

ランタイムの最適化がリードする

プロファイラが ないと、こんな単純なマシダはテストできない、一般的には、ループで書くか、テスターでテストすればいい、それにはスピードが重要だ