Ошибки, баги, вопросы - страница 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 хендлов и тп всегда только 10, но цены и график меняется же.

iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE)


билд 2652

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

код выдаёт значение  iRSI хендлов и тп всегда только 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() постоянное, скорее всего это обычная С++ функция , гуглится "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() постоянное, скорее всего это обычная С++ функция , гуглится "rand c++ source code"

инициализировать обязательно нужно, но если инициализировать константами, можно нарваться на оптимизацию

в общем не понятна нелюбовь к rand()

как вариант инициализироваться чем-нибудь таким:

будет быстро

речь была в том что при замерах надо мерять именно то что требуется, без лишнего

 
Alexandr Andreev:

речь была в том что при замерах надо мерять именно то что требуется, без лишнего

нет

если будут повторяющиеся участки кода - получите тестирование оптимизации!

какая разница сколько выполняется rand() ?

да пусть он выполняется 2/3 времени теста, главное чтобы время выполеения rand() было постоянным

ну и имхо, переключать контекст на выполнение системных функцций нужно, Ваш же MQL код будет использовать системные MQL-функции? - смысл идеальный код тестить?

Причина обращения: