Canvas vs Labels - page 6

 

Why would I want to test graphical drawings in a strategy tester (especially in a specialized version of visual pending), when it is better to do it directly in a working chart?

And congratulations to those who don't think to disable graphical plotting in their robots in the non-visual tester.

 

Nikolay is right - editing label properties has nothing to do with label rendering.

The label, like any other object on the chart, is drawn in a completely different thread and independently from the work of MQL5 program. The robot can only ask the chart to be forcefully rendered again, but can't measure the rendering time. Chart drawing with objects is completely asynchronous.

But rendering canvas is easy to measure as it is done directly in the flow of the robot and then during independent rendering of the chart it remains to do a native BitBlit of the bitmap ready in the context of the window. This operation is elementary and is well accelerated by the video card.

In text labels SetFont/TextOut in TTF fonts is quite expensive.
 
Mihail Matkovskij:

It turns out to be 321 times, if this measurement is to be believed.

This figure shows that this measurement cannot be trusted.
This is obvious to an experienced programmer.
Do you really think that there is any other way to display characters on a graphical screen except for their pixel-by-pixel formation? The days of the ECock are long gone.
 
Renat Fatkhullin:

Why would I want to test graphical drawings in a strategy tester (especially in a specialized version of visual pending), when it is better to do it directly in a working chart?

At the same time, congratulations to those who have not thought to disable graphical plotting in their trading robots in the non-visual tester.

I could have checked it on the chart as well. However, I thought it would be easier to do in the Strategy Tester. Besides, I had a situation, I described above, when the display was based on CCanvas and it seriously slowed down the Expert Advisor in the tester. Especially it was showing up on ticks. To demonstrate it in the chart, text output would have to be made in loop. That is, to make a great refresh rate, as it is done in my Expert Advisor with offline optimization that I am working on now. And I decided to do a label-based display for it, as Canvas would have slowed it down. Because, as you noted, the label is rendered in a different thread, so, it won't slow down the autonomous optimisation of the EA, which I have running in a loop.

It turns out, as you said, it takes more time to draw text in labels than to draw OBJ_BITMAP_LABEL. So, to make it faster, it also needs to be rendered in a separate thread. But how? If this cannot be done, then from the viewpoint ofan applicationthat usesOBJ_LABEL, it is faster than OBJ_BITMAP_LABEL...

 
Nikolai Semko:
This is obvious to an experienced programmer.

It is obvious for an experienced programmer who has studied in detail or knows the terminal thoroughly! And since I'm not a developer of the terminal, but only write applications for it, I may not know, like most programmers, what is not in the MQL documentation.

 
Mihail Matkovskij:

This is obvious to an experienced programmer who has studied in detail or knows the operation of the terminal thoroughly! And since I'm not a developer of the terminal, but only write applications for it, I may not know, like most programmers, what is not in the MQL documentation.

And yet you are trying to argue not just with a developer, but with the director of MQ.

 
Alexey Viktorov:

And yet you are trying to argue not just with a developer, but with the director of MQ.

I'm not trying to argue, but to find out if OBJ_BITMAP_LABEL can be made less costly than OBJ_LABEL from the point of view of the using application!

 
Mihail Matkovskij:

And I decided to make a label based display for it, as Kanvas would have slowed things down.

I'm pretty sure why your canvas was slowing down.
Because you were trying to cram multiple frames into one 30 millisecond frame.
The thing is, frames don't redraw (ChartRedraw) more often than about 30 frames per second anyway.

As I said here, the difference between kanvas text and Label is that the filling of the pixel array in the case of labels is asynchronous and not controlled by you, so the filling of the pixel array in the case of labels does not happen more often than once every about 30 milliseconds.
But it may happen with canvas because it is not asynchronous (bitmap filling). You may fill in the bitmap ten times in 30 milliseconds, but it will be displayed only once, and 9 times it will be idle.
Therefore, as discussed inCanvas is cool!, the programmer needs to control the BitMap start time.
A model of behaviour could be:

  • there is one function that forms the bitmap
  • the input of this function stores the start time in a static variable in milliseconds.
  • Next time you enter this function you should check if less than 30 milliseconds have passed since the last bitmap generation. If yes, then exit and return false, if no - start filling and output a new Bitmap.
It is more convenient, of course, to introduce bool variable into class, which allows or disallows forming the canvas.
 
Nikolai Semko:

I'm pretty sure why your kanvas was slowing down.
Because you were trying to cram multiple frames into one 30 millisecond frame.
The thing is, frames don't redraw (ChartRedraw) more often than about 30 frames per second anyway.

As I said here, the difference between kanvas text and Label is that the filling of the pixel array in the case of labels is asynchronous and not controlled by you, so the filling of the pixel array in the case of labels does not happen more often than once every about 30 milliseconds.
But it may happen with canvas because it is not asynchronous (bitmap filling). You may fill in the bitmap ten times in 30 milliseconds, but it will be displayed only once, and 9 times it will be idle.
Therefore, as discussed inCanvas is cool!, the programmer needs to control the BitMap filling time.
A model behavior could be as follows:

  • there is one function that forms the bitmap
  • the input of this function stores the start time of image generation in a static variable in milliseconds.
  • Next time you enter this function you should check if less than 30 milliseconds have passed since the last bitmap generation. If yes, then exit and return false, if no - proceed to fill and output a new Bitmap.
It would be better, perhaps, to introduce a variable in a class which allows creating a canvas.

Is there any information available somewhere where you can read more about it? Although everything is clear to me, but still, the topic is quite interesting! Now it remains to do the bitmap update control variant and test it. I'll be surprised if the bitmap turns out to be faster than the labels.

 

Here is an example, which shows what I am talking about. The basis of the script is taken from the documentation here .
It starts with a random array that outputs 100 times 100 lines and generates 100 labels.
It first outputs 100 frames with Label.
After that it will output 100 frames with canvas strings.
The canvas is the same.
In a loop Sleep is documented. If the loop contains Sleep(0), the situation will be quite different. You may experiment a bit.
All frames and lines are numbered for control.
I have recorded a video and slowed it down 30 times. You may see, that only two frames out of 100 were actually rendered for labels, moreover, in the second frame you can see that labels are from different frames, i.e. you can see the asynchrony working.

so these values for the Label are fake:

Kanvas outputs about 60-70 frames out of 100. This happened because the frame is formed a little bit faster than 30 milliseconds and therefore not all frames have time to be output, although all frames are formed.
Experiment with the top two parameters

and cycle delay.


If you increase the number of lines to be output, you might catch error 4001. This is a bug in MQ when there are too many outputs.

Files: