错误、漏洞、问题 - 页 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=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : loops=10000000000 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()几乎是不正确的,因为这个函数比其他命令的资源密集程度高一个数量级。

不太重要

rand()的执行时间是恒定的,很可能是一个普通的C++函数,谷歌 "rand c++源代码"

你必须初始化它,但如果你用常数初始化它,你可能会遇到优化问题

总的来说,我不理解对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++源代码"

你必须初始化它,但如果你用常数初始化它,你可能会遇到优化问题

总的来说,我不明白为什么不喜欢rand()。

作为一个变体,以类似这样的方式进行初始化。

将是快速的

重点是,你应该准确地测量你需要测量的东西,而不是任何无关紧要的东西。

 
Alexandr Andreev:

关键是要准确地测量所需的内容,没有任何额外的东西。

如果有重复的代码片段,你就会得到优化测试!

rand()执行多长时间有什么区别?

让它执行2/3的测试时间,主要的是rand()的时间应该是不变的。

您的MQL代码将使用系统的MQL-函数,对吗?- 测试一个完美的代码有什么意义?