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

 

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


Ниже сгенерированный код.

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

Для генерации был написан значительно лаконичнее по коду скрипт. Это может быть целесообразно, чтобы быстро проверить гипотезы и не допустить ошибок человеческого фактора.

 
fxsaber #:

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


Ниже сгенерированный код.

Для генерации был написан значительно лаконичнее по коду скрипт. Это может быть целесообразно, чтобы быстро проверить гипотезы и не допустить ошибок человеческого фактора.

Будьте осторожны, тот же ChatGPT допускает много ошибок, как в синтаксисе, так и в логике, поэтому надо всё перепроверять.

Но, подаван из него действительно знатный, помогает с выражением идеи в коде.

 
fxsaber #:

Ниже сгенерированный код.

Для генерации был написан значительно лаконичнее по коду скрипт. Это может быть целесообразно, чтобы быстро проверить гипотезы и не допустить ошибок человеческого фактора.

Не хватает исходной информации: новый код стал работать быстрее чем старый или нет?

Если нет, то зачем менять старый понятный код на новый непонятный!?

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

 
Aleksey Vyazmikin #:

Будьте осторожны, тот же ChatGPT допускает много ошибок, как в синтаксисе, так и в логике, поэтому надо всё перепроверять.

Но, подаван из него действительно знатный, помогает с выражением идеи в коде.

Генерирующий скрипт.

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

Не хватает исходной информации: новый код стал работать быстрее чем старый или нет?

Новый быстрее.

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

Это алгоритмическая оптимизация, а не компиляторная.

 
fxsaber #:

Новый быстрее.

Это алгоритмическая оптимизация, а не компиляторная.

Насколько быстрее? На 1.5% или в 1.5 раза? И будто быстрее? Или по результатам корректных замеров?

Т.е. Вы на вход подавали ему не код, а алгоритм?

 
A100 #:

Насколько быстрее? На 1.5% или в 1.5 раза? И по ощущениям или по конкретным замерам?

Т.е. Вы на вход подавали ему не код, а алгоритм?

Это в исходнике Virtual используется. На каждом тике нужно делать четыре проверки.

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


Но в некоторых ситуациях (switch 0-15) можно обойтись меньшим количеством проверок: 0-4. Это зависит от ТС.


Например, если ТС открывает/закрывает позиции только маркет-ордерами и не использует SL/TP, то ни одной проверки делать не надо.

А если используются все виды отложек одновременно - нужно делать все четыре проверки: ускорения не будет.


Поэтому нужно брать конкретную ТС и смотреть результаты замеров для нее. У разных ТС разные результаты ускорения.


Можно было классифицировать случаи (количество case) на больше вариантов. Не потянул, честно говоря.

 

В MQL5 есть функция StringReserve, используя которую мы, теоретически, можем сократить количество перераспределений памяти для нашей строки: распределили сразу достаточно большой буфер и далее работаем в нём.

Но, как показывает практика, любое последующее присвоение значения этой строке меняет размер её буфера (т.е., видимо, происходит перераспределение памяти).

В результате, вместо

string str;
str.Reserve(8192);
str="test";

есть смысл использовать

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

есть смысл использовать

Точно. Такой механизм отлично работает на дописывании строки. Например, при генерации больших HTML-отчетов.

 

Какими способоми можно узнать, есть ли у символа данные, чтобы не оставлять его в окне [Обзор Рынка], если их нет?

Я использую такую проверку в цикле:

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

Но после этого не получается вручную удалить символы из окна [Обзор Рынка] ни по одному ни все сразу, пока эксперт на графике:


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