Delayed drawing and chart updating with MT5/MQL5 - page 3

 
Doerk Hilger:

I do benchmarking with some macros. This is much more efficent to find bottlenecks because you get exact timings and surround the problem step by step. One should also keep in mind, that the code is really 1:1 between MT4 and MT5, its because I dont use any of the old MT4 functions and by this all code is almost 100% portable anyway.

 I mention this because in view of this, any profiling cannot tell me anything new, thats the problem. Maybe I call one million functions during startup, maybe more, I dont know, and when every functions takes some microseconds more, in the end its a million times these microseconds.

What I see is, that any function which results in mainly updating a bitmap or a chart object, takes much more time than before. And this makes no sense, because I dont update the chart itself more often than with MT4 and modify non-bitmap chart objects only while they are invisible.

I dont use Objectfind at all. Maybe you have some ideas more?

Maybe your code is too "1:1", from my experience there are a lot of little differences between mql4 and mql5 when working with graphical objects, maybe you missed one (or some) which slow down all the process ?

Like Fernando I didn't have a big graphical projects, so it's really difficult to say if it's an MT5 "bug" (or "feature" ;-)). Maybe you could ask to @Anatoli Kazharski which at least has experience with this kind of project ?

I suppose it's not possible to provide some sample code to reproduce the issue ? Yeah...I know

 

First, thank you for your effort guys. I appreciate that. 

@Alain ... well, the MT4 code is actually more MQL5 than it is MQL4. Pieces of source yes, but which? Its all nested ... anytime when I use the debugger to trace something, afterwards I have 20-30 source files opened :) In the meanwhile I found out at least that there seem to be some internal buffers which seem to overflow somehow, because after restarts the execution speed increases significantly, but still much slower than MT4. 

I remember that someone from the MQ support encouraged me to migrate from MQL4 to MQL5 because the execution speed should be better afterwards and should be similar to native DLLs ... well ;) I passed this issue to the support and lets see what the answer is. What I will try in the meanwhile is, I will modify the code so that any object of the chart will be created in a non visible area, means, instead of creating objects at x/y 0/0, i will create them at -5000/-5000, this should at least prevent the chart from trying to update something until I don´t want it. Lets see. But I am still not sure if its really the graphics part. 

I will also make some benchmark tests with string operations, file accesses and accesses to some internal data by using BlaBlaGetDouble(), BlaBlaGetString() and so on. If I find some significant differences, I will let you know. 

 
Doerk Hilger:

First, thank you for your effort guys. I appreciate that. 

@Alain ... well, the MT4 code is actually more MQL5 than it is MQL4. Pieces of source yes, but which? Its all nested ... anytime when I use the debugger to trace something, afterwards I have 20-30 source files opened :) In the meanwhile I found out at least that there seem to be some internal buffers which seem to overflow somehow, because after restarts the execution speed increases significantly, but still much slower than MT4. 

I remember that someone from the MQ support encouraged me to migrate from MQL4 to MQL5 because the execution speed should be better afterwards and should be similar to native DLLs ... well ;) I passed this issue to the support and lets see what the answer is. What I will try in the meanwhile is, I will modify the code so that any object of the chart will be created in a non visible area, means, instead of creating objects at x/y 0/0, i will create them at -5000/-5000, this should at least prevent the chart from trying to update something until I don´t want it. Lets see. But I am still not sure if its really the graphics part. 

I will also make some benchmark tests with string operations, file accesses and accesses to some internal data by using BlaBlaGetDouble(), BlaBlaGetString() and so on. If I find some significant differences, I will let you know. 

I never experimented MT5 being slower than MT4 (on live chart, it happened with the tester in specific conditions), at worst it's same speed. Of course, it's only my experience, I don't pretend it covers all cases (and certainly not a complex GUI).

  • So either you found some MT5 "bugs" (or features), hopefully the ServiceDesk will investigate.
  • Or you did something "wrong", in the sense it works with MT4 but not with MT5. You may have to change your approach in some way, MT5 is definitely not MT4.
  • Or the approach is ok, but some hidden bugs woke up under MT5.

Anyway, if you need practical help, let me know, and thanks to keep us posted in all cases.

 

Thank you ...

but where is this difference between MQL5 and MQL4? I dont see it at all. All the discussions here are about procedural programming, which I avoided from the very first line of code anyway. Of course, the handling of orders, but thats not a big deal too, just if you used the functions directly instead of organize them in classes as well.

Bout the graphical part, I made sure when I developed the base that it works with both, MT4 and MT5, before I continued with focusing on MT4 first. Not only that, I also cutted down some classes like CSymbolInfo etc. for usage with MT4 to be as close as possible to MT5 from the beginning. All what I did to migrate finally was kicking the few remaining native commands and put them in classes as well and include the uncutted classes instead of the cutted ones. Of course some few classes now contain some #ifdef __MQL5__ blocks, but not so much, its minimal, because for my understanding, MQL4 and MQL5 are 99% the same.

I really dont see this big difference, what do you mean by that?

 
Doerk Hilger:

Thank you ...

but where is this difference between MQL5 and MQL4? I dont see it at all. All the discussions here are about procedural programming, which I avoided from the very first line of code anyway. Of course, the handling of orders, but thats not a big deal too, just if you used the functions directly instead of organize them in classes as well.

Bout the graphical part, I made sure when I developed the base that it works with both, MT4 and MT5, before I continued with focusing on MT4 first. Not only that, I also cutted down some classes like CSymbolInfo etc. for usage with MT4 to be as close as possible to MT5 from the beginning. All what I did to migrate finally was kicking the few remaining native commands and put them in classes as well and include the uncutted classes instead of the cutted ones. Of course some few classes now contain some #ifdef __MQL5__ blocks, but not so much, its minimal, because for my understanding, MQL4 and MQL5 are 99% the same.

I really dont see this big difference, what do you mean by that?

I think that most OOP developers forget that, no matter how much OOP they code, they still end up needing to call the procedural functions of the underlying system.

So, even if MQL4 and MQL5 are very similar, the underlying systems are very different. Even the subtle differences in the MQL can be enough to "throw a wrench into the system" and complicate things very much, so imagine what the rest can do if not properly implemented to consider those very distinct differences.

 
Fernando Carreiro:

I think that most OOP developers forget that, no matter how much OOP they code, they still end up needing to call the procedural functions of the underlying system.

So, even if MQL4 and MQL5 are very similar, the underlying systems are very different. Even the subtle differences in the MQL can be enough to "throw a wrench into the system" and complicate things very much, so imagine what the rest can do if not properly implemented to consider those very distinct differences.


I know. All this stuff is collected in one file. Here are some benchmarks, measured within one tick in OnTick(), see for yourself:

MT5

2017.09.16 15:07:46.817 EA (EURUSD,M5) Profiler: Symbol (26 µs) OrderPool (1 ms) BidAsk (150 µs) Visuals (33 µs) Pipe (6 µs) PoolPanel (11 µs) StratOrder (19 µs) AutoExit (14 ms) ChartRedraw (9 µs) 

2017.09.16 15:07:47.146 EA (EURUSD,M5) Profiler: Symbol (22 µs) OrderPool (1 ms) BidAsk (49 µs) Visuals (33 µs) Pipe (6 µs) PoolPanel (12 µs) StratOrder (17 µs) AutoExit (107 µs) ChartRedraw (4 µs) 

2017.09.16 15:07:47.488 EA (EURUSD,M5) Profiler: Symbol (20 µs) OrderPool (917 µs) BidAsk (38 µs) Visuals (28 µs) Pipe (5 µs) PoolPanel (11 µs) StratOrder (45 µs) AutoExit (44 µs) ChartRedraw (4 µs) 


MT4

2017.09.16 15:12:08.787 EA EURUSD,M5:  Profiler: Symbol (20 µs) OrderPool (2 ms) BidAsk (19 µs) Visuals (20 µs) Pipe (4 µs) PoolPanel (4 µs) StratOrder (19 µs) AutoExit (52 µs) ChartRedraw (7 µs) 

2017.09.16 15:12:08.448 EA EURUSD,M5: Profiler: Symbol (20 µs) OrderPool (3 ms) BidAsk (11 µs) Visuals (19 µs) Pipe (4 µs) PoolPanel (5 µs) StratOrder (15 µs) AutoExit (47 µs) ChartRedraw (µs) 

2017.09.16 15:12:08.110 EA EURUSD,M5:  Profiler: Symbol (18 µs) OrderPool (1 ms) BidAsk (6 µs) Visuals (15 µs) Pipe (4 µs) PoolPanel (5 µs) StratOrder (10 µs) AutoExit (18 µs) ChartRedraw (5 µs) 


Remarks:

- "Symbol" - refrehing rates, update some data (No graphics within a tick)

- "Orderpool" this is -> Scan the orders/positions, select them, get data, calculate data, display orders (if any - here are none)

- "BidAsk" this is -> Read the quotes, show bid and ask lines, show price graphically. This is the part which uses the most graphic resources, including a light-calculation, and its not displayed for every tick, just every 333ms

- "Visuals" this is the execution of the function .OnTick() which may be used by all visual objects

- "PoolPanel" - panel to change data of opened orders (if any, none in this case, and also no graphical stuff here)

- "StratOrder" this is -> actually nothing, because it´s not turned on. In this case only comparing some variables (No graphics within a tick)

- "AutoExit" is -> Checking conditions for exit, such as equity, trade p/l, time et. (No graphics within a tick)

- "ChartRedraw" this is only the Command "ChartRedraw" which is only executed, if something needs to be redrawn after a tick


As you see, with any graphics or without, almost everything is executed slower in MT5, at round about 200%. Solely the function ChartRedraw() simply takes 150% more time. For what?

 

And by the way, if a panel executes its functions during a tick to compare the settings in edit-fields with order data, the values of all fields are buffered. So there is no graphics AND no access to the by ObjectGetString() to read its value or something like that. Pure MQL code, pure math. 

About the BidAsk with the most significant value, this is a CCanvas object, so actually NO graphics at all, just math with an array and allocation of memory sometimes.

Of course I could go deeper, but I see already here that there is one single conclusion: MT5 - is definetly - much slower than MT4 in ALL parts of the code and the graphics/math are simply the worst. 

 

If you want to test for yourself, here is some simple code. In MT5 already this simple math function takes 20-30% longer than in MT4.

#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(1);
      
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Speed test

      static ulong tsum=0;
      static int cnt=0;
      ulong t=GetMicrosecondCount();
      
      string s;
      for (int i=0;i<10000;i++)
         {
         //s+=(string)i;
         double r=MathMod(i,cnt);
         }
      
      t=GetMicrosecondCount()-t;
      tsum+=t;
      cnt++;
      Print("Duration: ",t," µs (Average: ",tsum/cnt," µs)");
   
  }
 
Doerk Hilger:

Thank you ...

...

I really dont see this big difference, what do you mean by that?

There are a lot of subtle differences (I don't think I talked about 'big difference' ?), I know that by experience. But I can't make a list sorry.

Take ObjectCreate(), it doesn't behave the same...depending on how you use it, it can be unnoticeable or problematic.

Doerk Hilger:

If you want to test for yourself, here is some simple code. In MT5 already this simple math function takes 20-30% longer than in MT4.

Are you seriously using MathMod() with integers ?

MT5

2017.09.16 15:07:46.817 EA (EURUSD,M5) Profiler: Symbol (26 µs) OrderPool (1 ms) BidAsk (150 µs) Visuals (33 µs) Pipe (6 µs) PoolPanel (11 µs) StratOrder (19 µs) AutoExit (14 ms) ChartRedraw (9 µs)

What is BidAsk ? Can you provide a sample code ?

 
Doerk Hilger:

If you want to test for yourself, here is some simple code. In MT5 already this simple math function takes 20-30% longer than in MT4.

MT5 gives me all 0 :

2017.09.19 19:59:37.866    Duration: 0 µs (Average: 0 µs)

Reason: