向#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倍以上,我正确地除以1 000 000,谁能告诉我这是什么原因?

炸弹。

这是你的代码,证明了它是相反的。

//+------------------------------------------------------------------+
#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:

什么测试? ))
你自己已经展示了循环条件的两种变化。
伊戈尔也给出了上面的代码。
只要在循环条件中使用变量大小和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。

在非常大的复赛中,我的胜利已经成为第一和第二种方法的随机性...最有可能的是,它变得取决于当前的CPU缓存和整体负载。

我的问题不是关于循环--而是关于函数如何展开的。只是作为一个例子是ArraySize

其结果是。

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


但是,如果我们在第二部分中加入对大小变量的初始化,那么第一种方法在初始化这个变量并将其等同于数值的时间上就占了先机。

 

如果你在循环的主体中改变数组的大小,即时优化就不起作用了

所以要修改代码。

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:

那么第一种方法优先,因为初始化这个变量并将其等同于一个值的时间,只有在高重复率时才会引人注目。

不出来

运行时优化将处于领先地位

如果没有剖析器,你无法测试这样简单的mashidas,一般来说,你可以写在一个循环中,或者你可以在测试器中测试,速度对它来说很重要。

原因: