Новая версия платформы MetaTrader 5 build 3550: улучшения и исправления - страница 31

 
Rashid Umarov #:

Посмотрите пример в статье https://www.mql5.com/ru/articles/1514

15 лет, оказывается, уже прошло.

Спасибо, прочел.

В моем понимании, шаблон советника - это некий универсальный прототип реального советника, лишенный конкретных специфических черт. Фактически, это некий СуперКласс, имеющий несколько чисто виртуальных функций (в терминах объектно-ориентированного программирования) или интерфейс (в терминах языка Java), если можно так выразиться. Шаблон описывает, что делает советник, но не описывает, как он это делает. Поэтому, прежде чем создавать данный шаблон, нам нужно произвести анализ требуемой функциональности. Нам необходимо предварительно создать для себя структуру советника.
Главное достоинство: разработано один раз - используется всегда. И при этом вероятность ошибочного кода нового советника также уменьшается.

Получается, что есть некая базовая болванка в виде mq5-файла. Делаем Save as и допиливаем, что нужно.

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

Видимо, с шаблонами какое-то исторические наследие тянется. 

 
fxsaber #:

Видимо, с шаблонами какое-то исторические наследие тянется. 

Шаблоны и сниппеты, в принципе да, историческое наследие.
Но с шаблонами намного быстрее начинать новую программу.
Сниппеты так-же ускоряют процесс ввода повторяющегося кода, в ходе разработки.
Такие фишки в основном реализованы в C редакторах, ввиду многословной структуры ЯП.
Чем и схож ЯП MQL5 - многословной структурой
Зачастую ООП по сути не нужен, если структура ЯП придерживается C-style.

 
Ilyas #:

Спасибо за сообщение.

Действительно при автогенерации оператора копирования для полей-массивов используется вызов ArrayCopy.

Исправлю, для массивов фиксированного размера буду использовать прямое копирование памяти там, где это возможно.

UPD: сделано

Спасибо, на b3584 данная проблема решилась. И обнаружился еще один сильнейший тормоз языка!

if (Pointer) // супер-медленно!
if (Pointer != NULL) // быстро.


Демонстрация.

class A {};

template <typename T>
int f1( const T* const Pointer ) { return(Pointer ? 1 : 0); }

template <typename T>
int f2( const T* const Pointer ) { return((Pointer != NULL) ? 1 : 0); }

void OnStart()
{
  int Res = 0;

  const ulong StartTime = GetMicrosecondCount();
  
  for (int i = 0; i < 1e8; i++)
//    Res += f1((bool)(MathRand() + 1) ? NULL : new A); // 382304 mcs.
//    Res += f2((bool)(MathRand() + 1) ? NULL : new A); // 226146 mcs.
    Res += f1(true ? NULL : new A); // 243218 mcs.
//    Res += f2(true ? NULL : new A); // 0 mcs.

  Print(GetMicrosecondCount() - StartTime);   
  Print(Res);    
}


Профилировщик показывает причину.

if (Pointer) // супер-медленно: CheckPointer?!
if (Pointer != NULL) // быстро.

Не совсем понимаю, зачем вообще CheckPointer вызывать в подобных ситуациях?

Однако, посмотрите на исходник демонстрации тормозов. Почему-то не происходит инлайна CheckPointer, как будто это не const-метод основного скопа.


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

Если недоработка, прошу оперативно ее устранить!

Строка для поиска: Uluchshenie 060.
 
fxsaber # :

Thanks, on b3584 this problem was solved. And another strong language brake was discovered!


Demonstration.


The profiler shows the reason.

I do not quite understand why CheckPointer should be called in such situations at all?

However, look at the brake demo source. For some reason, the CheckPointer inline does not occur, as if it were not a const method of the main scope.


It is clear that this language brake is bypassed by prescribing pointer comparisons with NULL everywhere. But it would be nice to understand if this is a serious compiler flaw or should it remain so?

If there is a problem, please fix it promptly!

Search string : Uluchshenie 060.
MQL5: Оператор "!" (LNOT) для указателя теперь проверяет его на валидность через неявный вызов функции CheckPointer . Для быстрой проверки на NULL следует использовать оператор "==". Например: ptr==NULL или ptr!=NULL.

Из пункта 7: https://www.mql5.com/ru/forum/425910

Новая версия платформы MetaTrader 5 build 3320: Улучшения и исправления - В четверг 2 июня 2022 года выпущена обновленная версия платформы MetaTrader 5
Новая версия платформы MetaTrader 5 build 3320: Улучшения и исправления - В четверг 2 июня 2022 года выпущена обновленная версия платформы MetaTrader 5
  • 2022.05.26
  • www.mql5.com
Terminal Исправлено обновление объектов, которыми отображается торговая история на графике. Ошибка возникала при изменении торгового инструмента у графика. Если включено отображение торговой истории на графиках
 
Alain Verleyen #:

Из пункта 7: https://www.mql5.com/ru/forum/425910

Спасибо огромное!

 
В версии для Mac OS не работает выбор цвета линий для нестандартных индикаторов.
 
Alain Verleyen #:

Из пункта 7: https://www.mql5.com/ru/forum/425910

Действительно в несколько раз быстрее.

Только нужно быть внимательнее, CheckPointer еще проверяет, существует ли объект по указателю

CObject *obj = new CObject;

Print( CheckPointer( obj ) != POINTER_INVALID );   // true
Print( obj != NULL );                              // true

delete obj;

Print( CheckPointer( obj ) != POINTER_INVALID );   // false
Print( obj != NULL );                              // true

Не забывать после удаления объекта присваивать указателю NULL, если он еще будет использоваться

Документация по MQL5: Общие функции / CheckPointer
Документация по MQL5: Общие функции / CheckPointer
  • www.mql5.com
CheckPointer - Общие функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

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


 
контрол со стрелкой позволяет уйти с поля и освободить курсор -  лучше чем за мышью бегать
 

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