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

 
fxsaber:

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

А я считаю, что первостепенная. От чего эффекта будет больше: от ускорения присвоения или от исключения его из кода?  Да, конечно бывают ситуации, когда это присвоение нужно само по себе, но часто ли такое встречается? В подавляющем большинстве случаев мы имеем дело лишь с временными переменными.

Да и насколько можно ускорить эти строковые операции - тоже вопрос. Вы так рассуждаете, будто там можно ускорить в разы. Сомневаюсь. Уже неоднократно там всё оптимизировали-переоптимизировали. Ну пусть удастся выжать ещё 20-30% - это погоды не сделает.

Кстати а вы не пробовали объявлять строковую переменную константой?

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

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

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

Ну это само собой.  И OrderSymbol тут ни при чём, равно как и MQL.  Строковые операции сами по себе затратные, поэтому обращаться к ним понапрасну не стоит.

 

Ну и так между делом

fxsaber:

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


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

надеюсь вы сами понимаете, что такой подход крайне неэффективен. Зачем получать PositionGetString на каждом тике? Что там может измениться?  Особенно учитывая, что вы сами эту позицию открывали, т.е. всё и так известно заранее.

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

 
Alexey Navoykov:

Да и насколько можно ускорить эти строковые операции - тоже вопрос. Вы так рассуждаете, будто там можно ускорить в разы. Сомневаюсь. Уже неоднократно там всё оптимизировали-переоптимизировали. Ну пусть удастся выжать ещё 20-30% - это погоды не сделает.

В разы.

Кстати а вы не пробовали объявлять строковую переменную константой?

Пробовал.
 
Alexey Navoykov:

Зачем получать PositionGetString на каждом тике? Что там может измениться?  Особенно учитывая, что вы сами эту позицию открывали, т.е. всё и так известно заранее.

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

Боевой робот с такой логикой - в такой то интервал времени по EURUSD не должно быть открытых позиций. Если есть - закрывай.

У Вас открыта GBPUSD-поза. Как выполнить условие выше без проверки OrderSymbol на каждом тике?

Или Вы предлагаете писать спец. версии советником именно для тестера? Вот человек купил боевого робота и тестит его. Написать в Маркете, что для тестера специально все оптимизировано по скорости?

 
fxsaber:

Боевой робот с такой логикой - в такой то интервал времени по EURUSD не должно быть открытых позиций. Если есть - закрывай.

У Вас открыта GBPUSD-поза. Как выполнить условие выше без проверки OrderSymbol на каждом тике?

Или Вы предлагаете писать спец. версии советником именно для тестера? Вот человек купил боевого робота и тестит его. Написать в Маркете, что для тестера специально все оптимизировано по скорости?

Ну достаточно же проверить только тикеты текущих открытых позиций (и соответственно вести массив по ним).  Если появился новый тикет, то по нему и проводить все остальные проверки.  Зачем по миллиону раз проверять одно и то же.

И кстати, в MQL5 есть же торговые события. Поэтому проверять на каждом тике незачем.

 
Alexey Navoykov:

Ну достаточно же проверить только тикеты текущих открытых позиций (и соответственно вести массив по ним).

Это будет ненамного дешевле.

И кстати, в MQL5 есть же торговые события. Поэтому проверять на каждом тике вообще незачем.

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

 
fxsaber:

Это будет ненамного дешевле.

Разница между операциями с целыми числами ненамного дешевле операций со строками?  Что ж, как вам угодно.

 
Alexey Navoykov:

Разница между операциями с целыми числами ненамного дешевле операций со строками?  Что ж, как вам угодно.

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

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

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

 

Отсутствие множественного наследования в MQL конечно удручает. Однако можно выкрутиться подручными способами: шаблонами и макросами - куда ж без них )

Вот такой вариант сваял.  Все исходные классы должны объявляться в виде шаблонов, задающих родительский класс.

class CBase { };  // базовый класс

// Макросы, задающие список наследования:

#define INHERIT1(T)  T<CBase>

#define INHERIT2(T1, T2)  T2<INHERIT1(T1)>

#define INHERIT3(T1, T2, T3)  T3<INHERIT2(T1,T2)>

#define INHERIT4(T1, T2, T3, T4)  T4<INHERIT3(T1,T2,T3)>


// Различные пользовательские классы:

template<typename TParent>
class A : public TParent { public: void a() { Print("A"); } };

template<typename TParent>
class B : public TParent { public: void b() { Print("B"); } };

template<typename TParent>
class C : public TParent { public: void c() { Print("C"); } };


class X : public INHERIT3(A, B, C)  {  };   // Объявляем класс, наследуемый от A, B, C


template<typename T>
void SomeFunc(B<T>& obj)  { obj.b(); }   // Проверочная функция, принимающая класс B


void OnInit()
{
  X x;
  x.a();
  x.b();
  x.c();
  
  SomeFunc(x);
}

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

 
Alexey Navoykov:

Отсутствие множественного наследования в MQL конечно удручает. Однако можно выкрутиться подручными способами: шаблонами и макросами - куда ж без них )

Вот такой вариант сваял.  Все исходные классы должны объявляться в виде шаблонов, задающих родительский класс.

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

Хороший прием. Вся фишка в применении шаблона к TParent. Не встречал раньше подобного.

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