Errors, bugs, questions - page 2879

 
Igor Makanu:

I've reworked it a bit

(it's better not to use a macro that way ;)

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

I've reworked it a bit

(so it's better not to use macro ;)

When testing, I confuse the code as much as possible to prevent the optimizer from throwing out empty loops

you have

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

Optimization of MQL execution may terminate the first loop beforehand, since the calculated values are not used, so something should be done after the SpeedTest() with the results - this loop

i checked it with the commented loop, i didn't throw it away, but in the other test i may crash


macro is a matter of taste, i have tested it many times and it works, i don't see the point of writing the same thing by hand



UPD: found where I read how modern compilers work now, pretty informative

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

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

 

the code gives the iRSI value of handles and tp is always only 10, but prices and graphs change, too.

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)


build 2652

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

the code gives the iRSI value of handles and tps always only 10, but the prices and the chart change, too.

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)


build 2652

You have got the indicator handle, it is 10

Next, you need to get the values on the right bar

//--- создадим хэндл индикатора
   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);
     }

Read the help, or search for answers on the forum - they are many

Документация по 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:

You have got the indicator handle, it is 10

Next, you need to get the values on the right bar

Read the help, or search for answers on the forum - there are many of them

Got it. I will study the buffers. It's strange, I had a feeling that everything should work as it is, maybe I confused it with mql4.

The strange thing is that I googled it and could not find it in mql5 to get indicator's data.


Aha, according to your example as I understood the value of indicator RSI is in the end in a variable of the following form

rsi_buffer[0] 
 
Igor Makanu:

checked:

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

the difference is not significant, it is highly probable that if we switch the tests in the opposite order, the results will be the opposite

not critical

it is hardly right to include rand() in the test since this function consumes much more resources than other commands.
I think this would be a more correct test:

#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;
   });
}

Result:

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

Fortunately, I've put it on the wrong horse after all. The unions are a bit faster. They are more convenient to work with and the code is more readable.

 
Nikolai Semko:

it is hardly correct to include rand() in the test, as this function is an order of magnitude more resource-intensive than the other commands.

not critical at all

rand() execution time is constant, most likely it is a common C++ function, google "rand c++ source code"

you must initialize it, but if you initialize it with constants you may encounter optimization

in general, i don't understand the dislike of rand()

an option is to initialize with something like this:

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]);
}

would be fast.


ran your script, imho not correct.

The main time is loading code into the cache and then into the processor

and add the discreteness of the system timer

we get... almost a random number.

you need to test it for a long time, about 100500 times, imho

 
Nikolai Semko:

It is unlikely to be correct to include rand() in the test, as this function consumes an order of magnitude more resources than the other commands.
I think this would be a more correct test:

Result:

Fortunately, I've bet on the wrong horse after all. The unions are a bit faster. They are more convenient to work with, and the code is more readable.


Once for once, and at a distance of the first win, (like the first method has removed the conversion line from short to something)

 
Igor Makanu:

not critical at all

rand() execution time is constant, most likely it is a common C++ function, google "rand c++ source code"

you must initialize it, but if you initialize it with constants you may encounter optimization

in general, I don't understand the dislike of rand()

as a variant to initialize with something like this:

will be fast

The point was that you should measure exactly what you need to measure, without any extraneous stuff.

 
Alexandr Andreev:

The point was to measure exactly what is required, with no extras

no

If there are repeated code fragments, you will get optimization testing!

What difference does it make how long rand() is executed?

let it be executed 2/3 of the test time, the main thing is that the rand() time should be constant

Your MQL code will use system MQL-functions, right? - what's the point of testing a perfect code?