Скачать MetaTrader 5

Профилировщик: вопросы, ошибки, пожелания

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Alexander Laur
7918
Alexander Laur  

Что бы несколько раз не запрашивать одни и тежи данные, ввожу локальные переменные и записываю в них один раз эти данные. На мой взгляд это разумно, так как скорость исполнения внутри терминала намного выше скорости исполения интернета. Например, вот так:

//---проверяем наличие открытой позиции
   if(PositionSelect(sy)){
      posType     = (int)PositionGetInteger(POSITION_TYPE);
      posOpPrice  = PositionGetDouble(POSITION_PRICE_OPEN);
      posVolume   = PositionGetDouble(POSITION_VOLUME);
      posProfit   = PositionGetDouble(POSITION_PROFIT);
   }

То есть я запрашиваю данные с сервера (чере интернет) один раз.Теперь, в процессе выполнения программы, я пользуюсь только этими переменными. Например:

         if(posProfit > 0){return(false);}

В отчете профилировщика в строке касающейся PositionGetDouble я вижу ссылку на строку if( posProfit > 0) { return(false); }

Получается, что я все-равно обращаюсь к данным на сервер? Или я чего то не понимаю? 

Документация по MQL5: Программы MQL5 / Выполнение программ
Документация по MQL5: Программы MQL5 / Выполнение программ
  • www.mql5.com
Программы MQL5 / Выполнение программ - Документация по MQL5
Alexander Laur
7918
Alexander Laur  

Вот код, который профилировал:

#property copyright "Copyright 2012, papaklass"
#property link      "https://www.mql5.com/ru/users/papaklass"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int      a = (int)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
   double   b = SymbolInfoDouble(Symbol(), SYMBOL_BID);
   
   double   f1 = Factorial_50();
   double   f2 = Factorial_100();
   
  }
//+------------------------------------------------------------------+
double Factorial_50(){
   double res = 1;
   
   for(int i = 1; i <= 500; i++){
      res *= i;
   }
   return(res);
}//------------------------------------------------------------------+
double Factorial_100(){
   double res = 1;
   
   for(int i = 1; i <= 1000; i++){
      res *= i;
   }
   return(res);
}//------------------------------------------------------------------+

А вот отчет профилировщика:

И где опять пользовательские функции Factorial_50(), которая считает 500! и функция Factorial_100(), которая считает 1000! 

Valerii Mazurenko
3484
Valerii Mazurenko  
papaklass:

Вот код, который профилировал:

А вот отчет профилировщика:

И где опять пользовательские функции Factorial_50(), которая считает 500! и функция Factorial_100(), которая считает 1000! 

Видимо компилятор их проинлайнил или вообще удалил, т. к. f1 и f2 не используются. Попробуйте использовать переменные:

Print(f1, f2);

 Если не поможет, то попробуйте дописать ещё несколько вызовов:

double   f3 = Factorial_50();
double   f4 = Factorial_100();
double   f5 = Factorial_50();
double   f6 = Factorial_100();
Print(f1, f2, f3, f4, f5, f6);

 

Alexander Laur
7918
Alexander Laur  

Загрузил ядро пользовательской функцией на 100%, а результат тот же. В отчете профилировщика нет пользовательских функций.

Из рисунка видно, что функция OnTick() пожирает время, а стандартные функции MQL5 ничего не тратят. Понятно, что все затраты относятся к работе пользовательских функций Fractal_50() и Fractal_60(), но они не включены в отчет. Почему?

Valerii Mazurenko
3484
Valerii Mazurenko  
papaklass:

Загрузил ядро пользовательской функцией на 100%, а результат тот же. В отчете профилировщика нет пользовательских функций.

Из рисунка видно, что функция OnTick() пожирает время, а стандартные функции MQL5 ничего не тратят. Понятно, что все затраты относятся к работе пользовательских функций Fractal_50() и Fractal_60(), но они не включены в отчет. Почему?

ф-ии используются один раз - компилятор мог их проинлайнить. Вызовите их хотя бы два раза (а лучше - три) и выведите результат (как в моём примере). Если Fractal_60 будет вызывать только Fractal_50, то и Fractal_60 в профайлере не увидите
Alexander Laur
7918
Alexander Laur  
notused:
ф-ии используются один раз - компилятор мог их проинлайнить. Вызовите их хотя бы два раза (а лучше - три) и выведите результат (как в моём примере). Если Fractal_60 будет вызывать только Fractal_50, то и Fractal_60 в профайлере не увидите

 Сделал, как Вы порекомендовали. Из кода видно, что вызываю пользовательские функции многократно. Результат отчета профилировщика не изменился. Пользовательских функций нет в отчете.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int      a = (int)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
   double   b = SymbolInfoDouble(Symbol(), SYMBOL_BID);
   
   double   f1 = Factorial_50();
   double   f2 = Factorial_60();
   double   f3 = Factorial_50();
   double   f4 = Factorial_60();
   double   f5 = Factorial_50();
   double   f6 = Factorial_60();
   
   Print("   f1 = ",f1,"   f2 = ",f2,"   f3 = ",f3,"   f4 = ",f4,"   f5 = ",f5,"   f6 = ",f6);
   
  }
//+------------------------------------------------------------------+
double Factorial_50(){
   double res = 1;
   
   for(int i = 1; i <= 1000; i++){
      res += (Factorial_60()+i);
   }
   return(res);
}//------------------------------------------------------------------+
double Factorial_60(){
   double res = 1;
   
   for(int i = 1; i <= 1000; i++){
      res += i;
   }
   return(res);
}//------------------------------------------------------------------+

 

Ilyas
1202
Ilyas  
Это наша ошибка, проблема действительно в инлайне.
Решение найдено и выйдет в следующем билде.

Вы можете "обмануть" инлайнер используя рекурсию, которая никогда не выполнится.
При наличии рекурсии, инлайнинг ПОКА не проводится.

bool ExtFalse=false;

double Factorial_60(){
   double res = 1;
   
   for(int i = 1; i <= 1000; i++){
      res += i;
   }

   if(ExtFalse)
     res+=Factorial_60;

   return(res);
}//------------------------------------------------------------------+

Alexander Laur
7918
Alexander Laur  
mql5:
Это наша ошибка, проблема действительно в инлайне.
Решение найдено и выйдет в следующем билде.

Вы можете "обмануть" инлайнер используя рекурсию, которая никогда не выполнится.
При наличии рекурсии, инлайнинг ПОКА не проводится.
 Спасибо за ответ. Ответьте, пожалуйста, на вопрос в первом посте.
Ilyas
1202
Ilyas  
papaklass:
 Спасибо за ответ. Ответьте, пожалуйста, на вопрос в первом посте.
Не понятно что такое "ссылка на строку". Приложите скриншот такого отчёта.
Alexander Laur
7918
Alexander Laur  
mql5:
Не понятно что такое "ссылка на строку". Приложите скриншот такого отчёта.
 Ситуацию, описанную в первом посте, воспроизвести не могу. Вопрос снимаю. Спасибо за внимание.
Alexander Laur
7918
Alexander Laur  

Пожелание:

Можно в профилировщике сделать паузу с выводом промежуточного отчета.

Нажал паузу. Посмотрел промежуточный отчет. Если посчитал, что проходов не достаточно, нажал кнопочку "продолжить", если достаточно - "остановить".

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий