Canvas vs Labels - страница 6

 

А зачем графические построения тестировать в тестере стратегий(да еще в специализированной версии визуального отложенного отображения), когда это лучше проверить прямо на рабочем чарте?

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

 

Николай прав - редактирование свойств лейблов не имеет никакого отношения к отрисовке лейбла.

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

А вот отрисовку в канвасе замерить легко, так как она производится прямо в потоке робота и потом во время независимой отрисовки чарта остается сделать нативный BitBlit готового битмапа в контекст окна. Эта операция элементарная и хорошо ускоряется видеокартой.

В текстовых лейблах SetFont/TextOut в TTF шрифтах достаточно дорогой.
 
Mihail Matkovskij:

Получается, что в 321 раз, если верить этому замеру. 

Эта цифра говорит как раз о том, что верить этому замеру нельзя. 
Это же очевидно для опытного программиста. 
Неужели вы думаете, что существует какой-то другой способ вывода символов на графический экран, кроме как их попиксельного формирования. Времена ЕСок давно прошли.
 
Renat Fatkhullin:

А зачем графические построения тестировать в тестере стратегий(да еще в специализированной версии визуального отложенного отображения), когда это лучше проверить прямо на рабочем чарте?

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

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

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

 
Nikolai Semko:
Это же очевидно для опытного программиста.

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

 
Mihail Matkovskij:

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

И тем не менее пытаетесь спорить не просто с разработчиком, а с директором компании MQ.

 
Alexey Viktorov:

И тем не менее пытаетесь спорить не просто с разработчиком, а с директором компании MQ.

Я пытаюсь не спорить, а узнать, можно ли сделать OBJ_BITMAP_LABEL менее затратным нежели OBJ_LABEL с точки зрения использующего приложения!

 
Mihail Matkovskij:

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

Я почти уверен, почему у вас канвас тормозил. 
Потому, что вы пытались засунуть в один 30-ти миллисекундный кадр несколько кадров.
Дело в том, что кадры все равно не перерисовываются (ChartRedraw) чаще, чем около 30 кадров в секунду.

Как я уже говорил здесь, что различие канвас текста и Label в том, что заполнение пикслельного массива в случае лейблов происходит асинхронно и вами не контролируется, поэтому заполнение пиксельного массива в случае лейблов не происходит чаще чем раз в примерно 30 миллисекунд.
А в случае канваса это может происходить, потому как этот процесс(заполнение битмапа) не является ассинхронным. И Вы можете десять раз заполнить битмап за 30 миллисекунд, а выведется на экран только один раз, а 9 раз работа была в холостую.
Поэтому, как уже обсуждалось в теме Canvas - это круто!, программисту нужно контролировать время начала заполнения БитМапа. 
Модель поведения может быть следующей:

  • существует одна функция, формирующая битмап
  • на входе этой функции запоминается время начала формирования изображения в статическую переменную в миллисекундах.
  • при очередном входе в эту функцию нужно проверять - не прошло ли менее 30 миллисекунд с момента начала последнего формирования Битмапа. Если да, - то выходим и возвращаем false, если нет - приступаем к заполнению и вывода нового Битмапа.
удобней, конечно, ввести bool переменную в класс, разрешающую или запрещающую формирование канваса.
 
Nikolai Semko:

Я почти уверен, почему у вас канвас тормозил. 
Потому, что вы пытались засунуть в один 30-ти миллисекундный кадр несколько кадров.
Дело в том, что кадры все равно не перерисовываются (ChartRedraw) чаще, чем около 30 кадров в секунду.

Как я уже говорил здесь, что различие канвас текста и Label в том, что заполнение пикслельного массива в случае лейблов происходит асинхронно и вами не контролируется, поэтому заполнение пиксельного массива в случае лейблов не происходит чаще чем раз в примерно 30 миллисекунд.
А в случае канваса это может происходить, потому как этот процесс(заполнение битмапа) не является ассинхронным. И Вы можете десять раз заполнить битмап за 30 миллисекунд, а выведется на экран только один раз, а 9 раз работа была в холостую.
Поэтому, как уже обсуждалось в теме Canvas - это круто!, программисту нужно контролировать время заполнения БитМапа. 
Модель поведения может быть следующей:

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

А есть ли в где-нибудь информация, где можно об этом почитать подробнее? Хоть мне всё и так понятно, но всё же, тема довольно интересная! Осталось теперь сделать вариант с контролем обновлений битмапа и протестировать. Буду удивлён, если битмап окажется быстрее лейблов. 

 

Вот набросал пример, из которого видно о чем я говорил.  Основу скрипта взял здесь из документации.
Здесь формируется в начале случайный массив для вывода 100 раз по 100 строк и формируется 100 Label.
Сначала выводятся 100 кадров с Label.
А потом 100 кадров с канвас строками.
Канвас один.
В цикле Sleep задокументирован. Если в цикле будет Sleep(0) - будет совсем другая картина. Можете поэкспериментировать.
Все кадры и строки пронумерованы для контроля.
Записал видео и замедлил его в 30 раз. Из него видно, что для лейблов реально вывелось всего два кадра из 100, причем во втором кадре видно, что лейблы из разных кадров, т.е. видна работа асинхронности.

поэтому эти значения для Label фейковые:

Канвас же вывел где-то 60-70 кадров из 100. Это произошло потому, что кадр формируется чуть быстее чем 30 миллисекунд и поэтому не все кадры успевают вывестись, хотя все формируются.
Экспериментируйте с двумя верхими параметрами 

и с задержкой в циклах.


При увеличении количества выводимых строк можно словить ошибку 4001. Это недоработка MQ, когда слишком много объктов.


 

Файлы:
Причина обращения: