Тестирование производительности работы с отдельными текстовыми метками и битмапами на чарте

 

Обсуждение началось тут: https://www.mql5.com/ru/forum/1111/page989#comment_480838

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

Тестирование велось на 64 битном MetaTrader 5 в Windows 8 x64 на слабенькой видеокарте NVIDIA GeForce GT 640M. Вот результаты (чем меньше время, тем лучше), полученные на тестовом скрипте:

2013.04.27 22:21:50	BenchmarkLabel (EURUSD,M15)	Тестирование завершено
2013.04.27 22:21:50	BenchmarkLabel (EURUSD,M15)	5. Время обновления текста и позиций у битмапа без прозрачности = 15007 ms
2013.04.27 22:21:35	BenchmarkLabel (EURUSD,M15)	4. Время обновления текста и позиций у битмапа с прозрачностью = 15257 ms
2013.04.27 22:21:20	BenchmarkLabel (EURUSD,M15)	3. Время обновления текста и позиций у меток со чтением = 16739 ms
2013.04.27 22:21:03	BenchmarkLabel (EURUSD,M15)	2. Время обновления текста и позиций у меток без чтения = 18845 ms
2013.04.27 22:20:44	BenchmarkLabel (EURUSD,M15)	1. Время обновления текста у меток без чтения = 21497 ms
2013.04.27 22:20:23	BenchmarkLabel (EURUSD,M15)	0. Время разогрева динамических очередей без визуализации = 124 ms
2013.04.27 22:20:23	BenchmarkLabel (EURUSD,M15)	Для корректного теста подберите размер окна 1024 x 768 пикселей, без индикаторов, не трогайте ничего, не сворачивайте и не закрывайте окна
2013.04.27 22:20:23	BenchmarkLabel (EURUSD,M15)	Разрешение чарта: 1020 x 761 пикселей

Видно, что работа с метками примерно на 60% медленнее работы с битмапами.

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

#property script_show_inputs

//---
input int   inRefreshCount=5000;
input int   inNumberOfLabels=26;
input color inTextColor=clrRed;

uint ExtCanvas[];
int  ExtBitmapWidth=20;             // вычислится автоматически
int  ExtBitmapHeight=20;            // вычислится автоматически
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- выведем разделитель для журнала и инициализируем рандом
   Print("");
   MathSrand(GetTickCount());
//--- покажем разрешение чарта
   Print("Разрешение чарта: ",ChartGetInteger(ChartID(),CHART_WIDTH_IN_PIXELS,0)," x ",ChartGetInteger(ChartID(),CHART_HEIGHT_IN_PIXELS,0)," пикселей");
   Print("Для корректного теста подберите размер окна 1024 x 768 пикселей, без индикаторов, не трогайте ничего, не сворачивайте и не закрывайте окна");
//--- cоздание меток
   CreateLabels();
   ChartRedraw(0);
//--- 0. холостой разогрев динамических очередей
   string name;
   uint   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      for(int j=0;j<inNumberOfLabels;j++)
        {
         name="ObjectLabel#"+IntegerToString(j);
         ObjectSetString(0,name,OBJPROP_TEXT,IntegerToString(MathRand()));
        }
     }
   ChartRedraw(0);
   Print("0. Время разогрева динамических очередей без визуализации = ",GetTickCount()-start," ms");
//--- 1. замерим скорость обновление меток (текст)
   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      for(int j=0;j<inNumberOfLabels;j++)
        {
         name="ObjectLabel#"+IntegerToString(j);
         ObjectSetString(0,name,OBJPROP_TEXT,IntegerToString(MathRand()));
        }
      ChartRedraw(0);
     }
   Print("1. Время обновления текста у меток без чтения = ",GetTickCount()-start," ms");
//--- 2. замерим скорость обновление меток (текст + смена позиций)
   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      for(int j=0;j<inNumberOfLabels;j++)
        {
         name="ObjectLabel#"+IntegerToString(j);
         ObjectSetInteger(0,name,OBJPROP_XDISTANCE,10+j*10+(i&3));
         ObjectSetInteger(0,name,OBJPROP_YDISTANCE,10+j*10+(i&3));
         ObjectSetString(0,name,OBJPROP_TEXT,IntegerToString(MathRand()));
        }
      ChartRedraw(0);
     }
   Print("2. Время обновления текста и позиций у меток без чтения = ",GetTickCount()-start," ms");
//--- 3. замерим скорость обновление меток (текст + смена позиций) со чтением позиций
   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      for(int j=0;j<inNumberOfLabels;j++)
        {
         name="ObjectLabel#"+IntegerToString(j);
         long pos=ObjectGetInteger(0,name,OBJPROP_XDISTANCE);
         ObjectSetInteger(0,name,OBJPROP_XDISTANCE,10+j*10+(i&3));
         ObjectSetInteger(0,name,OBJPROP_YDISTANCE,10+j*10+(i&3));
         ObjectSetString(0,name,OBJPROP_TEXT,IntegerToString(MathRand()));
        }
      ChartRedraw(0);
     }
   Print("3. Время обновления текста и позиций у меток со чтением = ",GetTickCount()-start," ms");
//--- переходим к тестам битмапа
   CreateBitmap();
   ChartRedraw(0);
//--- 4. замерим скорость отрисовки меток в канвасе с прозрачностью
   uint   textclr=ColorToARGB(inTextColor);

   name="ObjectBitmap";
   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      ArrayInitialize(ExtCanvas,0);
      for(int j=0;j<inNumberOfLabels;j++)
        {
         TextOut(IntegerToString(MathRand()),10+j*10+(i&3),10+j*10+(i&3),TA_LEFT|TA_TOP,ExtCanvas,ExtBitmapWidth,ExtBitmapHeight,textclr,COLOR_FORMAT_ARGB_RAW);
        }
      ResourceCreate("::"+name,ExtCanvas,ExtBitmapWidth,ExtBitmapHeight,0,0,ExtBitmapWidth,COLOR_FORMAT_ARGB_RAW);
      ChartRedraw(0);
     }
   Print("4. Время обновления текста и позиций у битмапа с прозрачностью = ",GetTickCount()-start," ms");
//--- 5. замерим скорость отрисовки меток в канвасе без прозрачности
   start=GetTickCount();

   for(int i=0;i<inRefreshCount && !IsStopped();i++)
     {
      ArrayInitialize(ExtCanvas,ColorToARGB(clrAqua));
      for(int j=0;j<inNumberOfLabels;j++)
        {
         TextOut(IntegerToString(MathRand()),10+j*10+(i&3),10+j*10+(i&3),TA_LEFT|TA_TOP,ExtCanvas,ExtBitmapWidth,ExtBitmapHeight,textclr,COLOR_FORMAT_XRGB_NOALPHA);
        }
      ResourceCreate("::"+name,ExtCanvas,ExtBitmapWidth,ExtBitmapHeight,0,0,ExtBitmapWidth,COLOR_FORMAT_XRGB_NOALPHA);
      ChartRedraw(0);
     }
   Print("5. Время обновления текста и позиций у битмапа без прозрачности = ",GetTickCount()-start," ms");
//--- удалим массив битмапа
   ArrayFree(ExtCanvas);
   Print("Тестирование завершено");
  }
//+------------------------------------------------------------------+
//| Создадим объекты                                                 |
//+------------------------------------------------------------------+
void CreateLabels(void)
  {
//--- удалим все объекты с чарта
   ObjectsDeleteAll(0);
//--- создадим метки
   string name;

   for(int i=0; i<inNumberOfLabels; i++)
     {
      name="ObjectLabel#"+IntegerToString(i);
      if(ObjectCreate(0,name,OBJ_LABEL,0,0,0))
        {
         ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);
         ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_UPPER);
         ObjectSetInteger(0,name,OBJPROP_XDISTANCE,10+i*10);
         ObjectSetInteger(0,name,OBJPROP_YDISTANCE,10+i*10);
         ObjectSetInteger(0,name,OBJPROP_COLOR,inTextColor);
         ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);
         ObjectSetInteger(0,name,OBJPROP_FONTSIZE,10);
         ObjectSetString(0,name,OBJPROP_FONT,"Courier New");
         ObjectSetString(0,name,OBJPROP_TEXT,name);
        }
     }
//---
  }
//+------------------------------------------------------------------+
//| Создаем битмап                                                   |
//+------------------------------------------------------------------+
void CreateBitmap(void)
  {
   string name="ObjectBitmap";
//--- удалим все объекты с чарта
   ObjectsDeleteAll(0);
//--- выделим место под битмап, занулим его
   ExtBitmapWidth=20+12*inNumberOfLabels;
   ExtBitmapHeight=20+10*inNumberOfLabels;
   ArrayResize(ExtCanvas,ExtBitmapWidth*ExtBitmapHeight);
   ArrayInitialize(ExtCanvas,0);
//--- создадим битмап и привяжем ресурс
   ObjectCreate(0,name,OBJ_BITMAP_LABEL,0,0,0);
   ObjectSetString(0,name,OBJPROP_BMPFILE,"::"+name);
//--- выставим размер текста
   TextSetFont("Arial",-90);
  }
//+---------------------------------------------------------------------------------------------------------------------------+
Файлы:
 

Кстати, с прозрачностью и без прозрачности не такое уж и большое отличие:

2013.04.27 18:24:32     BenchmarkLabel__1 (USDCHF,H1)   Тестирование завершено
2013.04.27 18:24:32     BenchmarkLabel__1 (USDCHF,H1)   5. Время обновления текста и позиций у битмапа без прозрачности = 13229 ms
2013.04.27 18:24:19     BenchmarkLabel__1 (USDCHF,H1)   4. Время обновления текста и позиций у битмапа c прозрачностью = 13994 ms
2013.04.27 18:24:05     BenchmarkLabel__1 (USDCHF,H1)   3. Время обновления текста и позиций у меток с чтением = 32229 ms
2013.04.27 18:23:33     BenchmarkLabel__1 (USDCHF,H1)   2. Время обновления текста и позиций у меток без чтения = 10671 ms
2013.04.27 18:23:22     BenchmarkLabel__1 (USDCHF,H1)   1. Время обновления текста у меток без чтения = 10733 ms
2013.04.27 18:23:11     BenchmarkLabel__1 (USDCHF,H1)   0. Время разогрева динамических очередей без визуализации = 187 ms
 
Да, это уже от эффективности видеодрайверов зависит.
 
2013.04.27 20:09:37     BenchmarkObjects (EURUSD,M5)    5. Время обновления текста и позиций у битмапа без прозрачности = 12558 ms
2013.04.27 20:09:24     BenchmarkObjects (EURUSD,M5)    4. Время обновления текста и позиций у битмапа с прозрачностью = 12839 ms
2013.04.27 20:09:11     BenchmarkObjects (EURUSD,M5)    3. Время обновления текста и позиций у меток с чтением = 2355 ms
2013.04.27 20:09:09     BenchmarkObjects (EURUSD,M5)    2. Время обновления текста и позиций у меток без чтения = 10655 ms
2013.04.27 20:08:58     BenchmarkObjects (EURUSD,M5)    1. Время обновления текста у меток без чтения = 10359 ms
2013.04.27 20:08:48     BenchmarkObjects (EURUSD,M5)    0. Время разогрева динамических очередей без визуализации = 124 ms

Какие-то результаты странные. Надо код посмотреть.

Однако, по-прежнему, скорость работы с метками выше битмапа.


Тестирование велось на 64 битном MetaTrader 5 в Windows 7 x64 на слабенькой видеокарте NVIDIA GeForce GT 330M.

 
Надо собрать штук 10 результатов с указанием вида операционки и видеокарты.

Тестировать надо одном открытом чарте, открытом на полный экран, без индикаторов и без переключений окон или скрытия окна.

Так как эта задача прямо зависит от отрисовки, то недопустимо сворачивать, минимизировать или тестировать на мизерных размерах окон.

Проведите еще раз тесты на полностью открытом окне без переключений.
 
Тест делал по правилам.

2013.04.27 19:20:00     OpenCL  Device #0: GPU NVIDIA Corporation GeForce GT 430 with OpenCL 1.1 (2 units, 1400 MHz, 1023 Mb, version 296.10, rating 159)
2013.04.27 19:19:58     Terminal        MetaTrader 5 build 803 started (MetaQuotes Software Corp.)
WinXP SP3 x86 3Гц RAM 3Гб

2013.04.27 19:34:53     BenchmarkLabel__1 (EURUSD,H1)   Тестирование завершено
2013.04.27 19:34:53     BenchmarkLabel__1 (EURUSD,H1)   5. Время обновления текста и позиций у битмапа с прозрачностью = 38672 ms
2013.04.27 19:34:14     BenchmarkLabel__1 (EURUSD,H1)   4. Время обновления текста и позиций у битмапа с прозрачностью = 39140 ms
2013.04.27 19:33:35     BenchmarkLabel__1 (EURUSD,H1)   3. Время обновления текста и позиций у меток со чтением = 128203 ms
2013.04.27 19:31:27     BenchmarkLabel__1 (EURUSD,H1)   2. Время обновления текста и позиций у меток без чтения = 33000 ms
2013.04.27 19:30:54     BenchmarkLabel__1 (EURUSD,H1)   1. Время обновления текста у меток без чтения = 31969 ms
2013.04.27 19:30:22     BenchmarkLabel__1 (EURUSD,H1)   0. Время разогрева динамических очередей без визуализации = 281 ms
2013.04.27 19:30:21     BenchmarkLabel__1 (EURUSD,H1)
 
5 пункт надо читать без прозрачности, забыл вывод поправить
 

Ранее был билд 794. Вот тест с 803.

2013.04.27 20:59:43     BenchmarkObjects (EURUSD,M1)    5. Время обновления текста и позиций у битмапа без прозрачности = 5101 ms
2013.04.27 20:59:38     BenchmarkObjects (EURUSD,M1)    4. Время обновления текста и позиций у битмапа с прозрачностью = 5195 ms
2013.04.27 20:59:33     BenchmarkObjects (EURUSD,M1)    3. Время обновления текста и позиций у меток с чтением = 4103 ms
2013.04.27 20:59:29     BenchmarkObjects (EURUSD,M1)    2. Время обновления текста и позиций у меток без чтения = 3557 ms
2013.04.27 20:59:25     BenchmarkObjects (EURUSD,M1)    1. Время обновления текста у меток без чтения = 3338 ms
2013.04.27 20:59:22     BenchmarkObjects (EURUSD,M1)    0. Время разогрева динамических очередей без визуализации = 109 ms

Если можно, объясните мне, пожалуйста, практический смысл тестов 2 и 3?

И ещё вопросик. Можно вкратце "на пальцах" объяснить разницу между COLOR_FORMAT_ARGB_RAW и COLOR_FORMAT_ARGB_NORMALIZE?

 

Очень разные у всех результаты однако. Мой тест был на Windows 7 x64 и NVIDIA GeForce 9600GTMT5 build 803.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Тестирование производительности работы с отдельными текстовыми метками и битмапами на чарте

tol64, 2013.04.27 17:26

Кстати, с прозрачностью и без прозрачности не такое уж и большое отличие:

2013.04.27 18:24:32     BenchmarkLabel__1 (USDCHF,H1)   Тестирование завершено
2013.04.27 18:24:32     BenchmarkLabel__1 (USDCHF,H1)   5. Время обновления текста и позиций у битмапа без прозрачности = 13229 ms
2013.04.27 18:24:19     BenchmarkLabel__1 (USDCHF,H1)   4. Время обновления текста и позиций у битмапа c прозрачностью = 13994 ms
2013.04.27 18:24:05     BenchmarkLabel__1 (USDCHF,H1)   3. Время обновления текста и позиций у меток с чтением = 32229 ms
2013.04.27 18:23:33     BenchmarkLabel__1 (USDCHF,H1)   2. Время обновления текста и позиций у меток без чтения = 10671 ms
2013.04.27 18:23:22     BenchmarkLabel__1 (USDCHF,H1)   1. Время обновления текста у меток без чтения = 10733 ms
2013.04.27 18:23:11     BenchmarkLabel__1 (USDCHF,H1)   0. Время разогрева динамических очередей без визуализации = 187 ms

 

делал 2 теста первый раз переключил окно

Win XP SP3 ), ATI интегрированная, MT5 build 787

кстати заметил при открытом окне "о программе" в МТ5, через клавиши Alt+Tab не видна иконка терминала

 
Во время прохождения третьего теста только у меня график намертво зависает?
Причина обращения: