Особенности языка mql5, тонкости и приёмы работы - страница 49

 
fxsaber:

Если сразу после слов if, else, while, for, do нажать TAB, будет небольшое доп. построение...


елы-палы.. класс, после лет 5 знакомства с мql - узнала. 

 

Выводы из  разговора в СД по поводу одной поднятой проблемы.

Оказывается, что присвоение значения строковой переменной является ОЧЕНЬ дорогой операцией.

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


Как пример, если запустить на ФИБО прогон по реальным тикам за месяц, это будет около 1 млн тиков. Если на каждом тике получать значение PositionGetString и сравнивать его с чем-нибудь, то производительность будет приемлема, но если перед сравнением сначала результат функции присвоить string-переменной, а потом ее сравнить, то длительность прогона увеличит где-то на секунду.


Если кажется, что это мелочь, то это ошибочное видение. Когда такой советник запускается в режиме оптимизации на несколько тысяч проходов, то эта доп. секунда выливается в доп. часы ожидания. Т.е. безобидное стринг-присвоение может вызвать доп. часы ожидания при оптимизации. Будьте аккуратны и учитывайте этот нюанс.


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

 
fxsaber:

Выводы из  разговора в СД по поводу одной поднятой проблемы.

Оказывается, что присвоение значения строковой переменной является ОЧЕНЬ дорогой операцией.

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


Как пример, если запустить на ФИБО прогон по реальным тикам за месяц, это будет около 1 млн тиков. Если на каждом тике получать значение PositionGetString и сравнивать его с чем-нибудь, то производительность будет приемлема, но если перед сравнением сначала результат функции присвоить string-переменной, а потом ее сравнить, то длительность прогона увеличит где-то на секунду.


Если кажется, что это мелочь, то это ошибочное видение. Когда такой советник запускается в режиме оптимизации на несколько тысяч проходов, то эта доп. секунда выливается в доп. часы ожидания. Т.е. безобидное стринг-присвоение может вызвать доп. часы ожидания при оптимизации. Будьте аккуратны и учитывайте этот нюанс.


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

Спасибо, вот уж не думал что такое возможно. Учту в будущих разработках 

 

Простая загадка на ночь, почему желтые результаты?

struct INT
{
  int Array[];
  
  INT()
  {
    Print(__FUNCTION__); // до сюда не дойдет
  }
};

void OnStart()
{
  INT i = {0};
  
  Print(ArrayResize(i.Array, 5)); // -1
}
 
fxsaber:

Простая загадка на ночь, почему желтые результаты?

Потому что структура забивается нулями, а не конструктором, из-за этого неправильо инициализируется структура массива, arrayresize такие массивы не любит, у меня вообще код крешился на таком ресайзе.
 
Комбинатор:
Потому что структура забивается нулями, а не конструктором, из-за этого неправильо инициализируется структура массива, arrayresize такие массивы не любит, у меня вообще код крешился на таком ресайзе.

Это хорошо, что все об этом знают.

 
Slava:

Имеется в виду GetMicrosecondCount. Нельзя сказать определённо, тормозит ли он сервер. Он может оказать опосредованное влияние. Поэтому лучше использовать родной для системы GetTickCount

GetMicrosecondCount используется для замера коротких участков выполнения кода. Для замера выполнений большого множества OnTick лучше всё-таки GetTickCount

Попробуйте после получения стабильных результатов вместо GetTickCount использовать GetMicrosecondsCount. Потом расскажете здесь. Может быть я зря так волнуюсь

Ваша гипотеза оказалась верна, множественный вызов GetMicrosecondsCount вызывает жуткие тормоза в тестере. Однако, GetTickCount влияет так же.
 
fxsaber:

Выводы из  разговора в СД по поводу одной поднятой проблемы.

Оказывается, что присвоение значения строковой переменной является ОЧЕНЬ дорогой операцией.

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


Как пример, если запустить на ФИБО прогон по реальным тикам за месяц, это будет около 1 млн тиков. Если на каждом тике получать значение PositionGetString и сравнивать его с чем-нибудь, то производительность будет приемлема, но если перед сравнением сначала результат функции присвоить string-переменной, а потом ее сравнить, то длительность прогона увеличит где-то на секунду.


Если кажется, что это мелочь, то это ошибочное видение. Когда такой советник запускается в режиме оптимизации на несколько тысяч проходов, то эта доп. секунда выливается в доп. часы ожидания. Т.е. безобидное стринг-присвоение может вызвать доп. часы ожидания при оптимизации. Будьте аккуратны и учитывайте этот нюанс.


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

struct STRUCT
{
  string Str;
  
  string Get() const { return(this.Str); }
};

void OnStart()
{
  STRUCT Struct;
  
  Print(Struct.Str);
  Print(Struct.Get()); // Выполняется гораздо дольше, чем предыдущая строка
}
 
fxsaber:

Оказывается, что присвоение значения строковой переменной является ОЧЕНЬ дорогой операцией.

...

если перед сравнением сначала результат функции присвоить string-переменной, а потом ее сравнить, то длительность прогона увеличит где-то на секунду.

Как я понимаю, проблема не столько в дороговизне присвоения, сколько в том, что компилятор почему-то не вырезает из кода это лишнее присвоение, хотя должен бы.  Т.е. скомпилированный код должен получаться одинаковым в обоих случаях.
 
Alexey Navoykov:
Как я понимаю, проблема не столько в дороговизне присвоения, сколько в том, что компилятор почему-то не вырезает из кода это лишнее присвоение, хотя должен бы.  Т.е. скомпилированный код должен получаться одинаковым в обоих случаях.

Это второстепенная проблема. Да, оптимизатор компилятора еще не умеет оптимизировать такие строковые моменты. Но проблема замедления именно в присвоении стринга.

Напишите код, который невозможно оптимизировать компилятором, но при этом сделайте в нем присвоение. И увидите тормоза.

А пример с чтением стринг-поля структуры через функцию - это как раз то, как реализовано чтение свойств позиции в MT4/5.

В MT4 тот же OrderSymbol() - это тормоза, если его реализовывать в MT5. Сами разработчики стараются передавать в свои функции строки через ссылки.

Поэтому, если пишите что-то такое

if ((OrderSymbol() == Symb) && (OrderMagicNumber == Magic))

всегда лучше OrderSymbol-условие запихивать в конец общего условия.


В общем, увидел явное замедление на казалось бы ровном месте, когда стал использовать TesterBench.

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