Мой подход. Ядро - Движок. - страница 85

 

К разговору об интуиции. Хочу привести интересный пример. Мой пост, напечатанный в этой теме https://www.mql5.com/ru/forum/95632/page12    более двух лет назад:

Реter Konow:

1. Концепция графического движка.

2. Концепция графического ядра.

3. Этапы создания визуальной студии для платформы МТ.

4. Описание механизма создания интерфейса советника.


1. Графический движок представляет из себя программу выполненную в качестве индикатора. Данная программа создана исключительно для управления пользовательским интерфейсом. Выполняет набор базовых функций: 

  • Загрузку ядра графического интерфейса из файла.
  • Сохранение пользовательских настроек интерфейса.
  • Осуществление единого и слаженного управления всеми процессами в интерфейсе. Реализует "механику" управления интерфейсом, в понятие которой входят: открытие и закрытие окон, изменение размеров окон, перемещение окон, объединение окон, масштабирование, проигрывание сценариев, смена состояний объектов, привязки объектов, управление значениями параметров элементов управления в соответствии с их типами и свойствами, создание и уничтожение глоб. переменных.

     Графический движок добавляется на график также, как и любой другой индикатор. Он включает в себя следующий набор окон: 

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

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



2. Графическое ядро это блок информации, содержащий в себе данные всех объектов и окон интерфейса, записываемый в массиве и сохраняемый в файле. 

Этот блок является цифровым отражением графического интерфейса. Загружается графическим движком по указанию пользователя. Сам графический движок имеет свое собственное, внутреннее граф. ядро которое обеспечивает работу его собственных окон, и внутри этого ядра отведено свободное место для интеграции в него пользовательского интерфейса (в цифровом виде). Интеграция осуществляется в процессе загрузки графического ядра из файла. 


3. Создание визуальной студии на платформе МТ, в моем понимании делится на два этапа:

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


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

   Дело в следующем: в движке имеется спец. функция, которая создает полноценное графическое ядро на основе одного файла, с минимальным количеством загрузочной информации. Загрузочная информация в этом файле имеет самопонятный и читабельный для человека вид. Ее легко писать и редактировать. Например, для создания окна досточно написать "_CREATE_NEW_WINDOW", а для создания чекбокса "_CHECKBOX" и имя этого чекбокса, (движок автоматически распознает имя элемента, как наименование самого элемента и как наименование его параметра). 

Данная функция называется "G_CORE_BUILDER()" и она строит графическое ядро принимая данные из двух основных источников: из загрузочного файла создаваемого пользователем, и из массива "CONTENT[]", в котором записаны все стандартные группы объектов входящие в состав платформ окон и элементов управления. "CONTENT[]" содержит также состояния и сценарии объектов. Все в одном массиве. В общем, исходный материал из "CONTENT[]" + загрузочный файл создаваемый пользвателем используются функцией "G_CORE_BUILDER()" для построения графического ядра, с которым работает движок. 

Приход нового поколения торговых программ. Каким должен стать интерфейс советников?
Приход нового поколения торговых программ. Каким должен стать интерфейс советников?
  • 2016.09.19
  • www.mql5.com
Уважаемые разработчики, в преддверии скачка развития торговых программ, ожидается что создаваемые нами роботы преобретут массу новых возможностей...
 

Удивительно, насколько НЕИЗМЕНИЛИСЬ термины и концепции за ДВА ГОДА упорного труда. И функции и массивы и ключ.слова, - в как здесь сказано. Все реализовано по этому сценарию. И эта технология работает и развивается. При том, что два года назад, опыта разработки языка разметки у меня НЕ БЫЛО СОВСЕМ. 

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

Если это не пророческая интуиция, то что тогда?

 

Уважаемые оппоненты.

Вот код скрипта, который: 

  1. Замеряет время перевода строки в массив Char, для передачи строки в другую программу через ресурс и время извлечения строки из массива Char для последующего разбития и извлечения информации.
  2. Замеряет время записи строки в описание МТ-объекта и время получения строки из описания МТ-объекта, для последующего разбития и извлечения информации. 
//+------------------------------------------------------------------+
//|                        CharArrayToString и StringToCharArray.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
//--------------------------------------------

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   string qwerty = "qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj";   
   uchar Arr[];
   //---------------------------------
   //Создаем объект связи.
   //---------------------------------
   ObjectCreate(0,"button_1",OBJ_BUTTON,0,0,0);   
   //---------------------------------
   ulong t1 = GetMicrosecondCount();
   //---------------------------------
   //Переводим строку в тип Char
   //---------------------------------
   StringToCharArray(qwerty,Arr,0,WHOLE_ARRAY);
   //---------------------------------
   ulong t2 = GetMicrosecondCount();
   //---------------------------------
   //Переводим массив Char обратно в строку:
   //---------------------------------
   string str_1 = CharArrayToString(Arr,0,WHOLE_ARRAY);
   //---------------------------------
   ulong t3 = GetMicrosecondCount();
   //---------------------------------
   //Записываем строку в описании МТ-объекта.
   //---------------------------------
   ObjectSetString(0,"button_1",OBJPROP_TEXT,"qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj");
   ulong t4 = GetMicrosecondCount();
   //---------------------------------
   //Cчитываем строку из описания МТ-объекта.
   //---------------------------------
   string str_2 = ObjectGetString(0,"button_1",OBJPROP_TEXT);
   ulong t5 = GetMicrosecondCount();
   //---------------------------------   
   //Замеряем время исполнения.
   //----------------------------------------------
   Print("Time of execution StringToCharArray:   ",t2-t1);
   Print("Time of execution CharArrayToString:   ",t3-t2," строка от CharArrayToString:  ",str_1);
   //----------------------------------------------
   Print("Time of execution ObjectSetString:     ",t4-t3);
   Print("Time of execution ObjectGetString:     ",t5-t4," строка от ObjectGetString:  ",str_2);
   //----------------------------------------------
  }
//+------------------------------------------------------------------+

Результат:

2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution StringToCharArray:   47
2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution CharArrayToString:   35 строка от CharArrayToString:  qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj

2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution ObjectSetString:     3
2018.12.18 16:44:20.042 CharArrayToString и StringToCharArray GBPUSD,M5: Time of execution ObjectGetString:     3 строка от ObjectGetString:  qierfhqoerifhqoiwerufhqoiwerfhwioefhqowasdkfj


 

Мое решение более чем в 10 раз быстрее.

Прибавьте к вашему решению, время на сохранение ресурса и время на получение ресурса в массив с помощью ResourceReadImage();

В моем варианте решения, ни первое, ни второе НЕ ТРЕБУЕТСЯ.

 
Реter Konow:
Мое решение более чем в 10 раз быстрее.

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

 
Vasiliy Sokolov:

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

Василий, а как еще передавать данные всех типов между программами? 

OnChartEvent() подходит частично. 

  1. Не работает в тестере.
  2. При большом количестве вызовов - забивается очередь событий.


 
И кстати, замеры меньше 20 милисекунд, строго говоря вообще не валидны, по крайней мере в системах с вытесняющей многопоточносью. Но даже если принять твой результат (в целом я это признаю), все равно это ни о чем не говорит, потому что важны издержки с учетом полного круга. А то, что ты померил, это лишь часть этого.  
 
Vasiliy Sokolov:
И кстати, замеры меньше 20 милисекунд, строго говоря вообще не валидны, по крайней мере в системах с вытесняющей многопоточносью. Но даже если принять твой результат (в целом я это признаю), все равно это ни о чем не говорит, потому что важны издержки с учетом полного круга. А то, что ты померил, это лишь часть этого.  

Нужен универсальный и самый быстрый способ. Чтобы и в тестере работал и в обход очереди событий OnChartEvent();

Как показала проверка, передача через ресурсы в 10 раз медленнее. (без замера времени на сохранение ресурса и получения из него данных с помощью ResourceReadImage()) .

Мое решение - лучший вариант при исходных условиях.

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

Верно, но если экстраполировать на большее количество строк и передач, мой вариант все равно выигрывает.

 
Реter Konow:

Василий, а как еще передавать данные всех типов между программами? 

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