Simple EA Optimization: Declaring 2 times the main culprit about these EA's speed?

To add comments, please log in or register
nadiawicket
965
nadiawicket  

These 2 EA's execution speeds are very different, I take it due to the fact that in first one there is the declaration at top and in the second one there is only the declaration inside the OnTick() function.

Is this all there's to it?

//+------------------------------------------------------------------+
//|                                                       TestEA.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

int a;
double b;
string c;
string d;
double e;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Print(GetMicrosecondCount());

   a=2321;
   b=21.123;
   c="whatever";
   d="whatever2";
   e=Bid+21*Point;

   if(a+b>10)
      Print("Greater");
   else
      Print("NonGreater");

   Print(StringConcatenate(c,a,b));

   Print(StringConcatenate(c,a,b,d,e));

   Print(GetMicrosecondCount());
  }
//+------------------------------------------------------------------+

The second, really faster in microseconds version declaring only once inside the OnTick():

//+------------------------------------------------------------------+
//|                                                      TestEA2.mq4 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Print(GetMicrosecondCount());

   int a=2321;
   double b=21.123;

   if(a+b>10)
      Print("Greater");
   else
      Print("NonGreater");

   string c="whatever";

   Print(StringConcatenate(c,a,b));

   double e=Bid+21*Point;
   string d="whatever2";

   Print(StringConcatenate(c,a,b,d,e));

   Print(GetMicrosecondCount());
  }
//+------------------------------------------------------------------+

This speed difference is just due to declaring both on top and in the OnTick? The compiler "translates" it all the same no matter if its on top or inside OnTick?

Using functions as well are so much faster than rewriting the whole function process every single time for what seems to be the same reason. Just found out.

If you know any more such speed saving coding efficiency tips please let me know.

Code profiling - Developing programs - MetaTrader 5
Code profiling - Developing programs - MetaTrader 5
  • www.metatrader5.com
Profiling means collecting program parameters during its execution. During a profiling, the execution time and the number of calls of individual functions and program code lines are measured. With this tool, the programmer is able to find and optimize the slowest code sections. Profiling can be performed on the normal chart of the trading...
William Roeder
19863
William Roeder  
  1. You aren't seeing anything but clock jitter.

    In the first version, the allocation/deallocation of the variables occurs outside of your functions, so you aren't measuring everything. In the second version you are.

    Do your OnTick code a few billion times and you'll see no difference. Just like in your other, useless thread.

  2. Stop looking at inconsequential things. Look at things that matter.

    1. EAs : Don't do per tick that you can do per bar, or on open.
      If you are waiting for a level, don't reevaluate, wait until price reaches it (or a new bar starts and you recalculate.)
      If you are waiting for an order to open or close, only look when OrdersTotal (or MT5 equivalent) has changed.
                How to get backtesting faster ? - MT4 - MQL4 programming forum
    2. Indicators: Code it properly so it only recomputes bar zero (after the initial run.)
                How to do your lookbacks correctly.
      Or, reduce Tools → Options (control-O) → Charts → Max bars in chart to something reasonable (like 1K.)

nadiawicket
965
nadiawicket  
William Roeder:

Just like in your other, useless thread

Cause you never asked that question or anything that can be learned from that thread

Alain Verleyen
39060
Alain Verleyen  
nadiawicket:

These 2 EA's execution speeds are very different, I take it due to the fact that in first one there is the declaration at top and in the second one there is only the declaration inside the OnTick() function.

Is this all there's to it?

The second, really faster in microseconds version declaring only once inside the OnTick():

This speed difference is just due to declaring both on top and in the OnTick? The compiler "translates" it all the same no matter if its on top or inside OnTick?

Using functions as well are so much faster than rewriting the whole function process every single time for what seems to be the same reason. Just found out.

If you know any more such speed saving coding efficiency tips please let me know.

You should provide the results, what is "very different" for you ?

nadiawicket
965
nadiawicket  
Alain Verleyen:

You should provide the results, what is "very different" for you ?

The printed before and after microsecond counts are generally higher on the first version, which in my level of understanding seems to imply that its a slower version than the second.

Alain Verleyen
39060
Alain Verleyen  
nadiawicket:

The printed before and after microsecond counts are generally higher on the first version, which in my level of understanding seems to imply that its a slower version than the second.

I understood that, I am asking you the actual numbers.
nadiawicket
965
nadiawicket  
Alain Verleyen:
I understood that, I am asking you the actual numbers.

Looks like its just the variable allocation on the first pass of the OnTick where we need to read whats below property strict, unlike in subsequent passes of the OnTick.  This explains why its normalized to 60000 microseconds after the first pass on both EA's. Weird thing is that this should affect the exact first pass, not second pass and after.

FirstEA:


Second

EA


You just skip allocation of variables on the first pass if you declare inside OnTick to the best of my understanding. Why then the first pass is the same for both? Shouldn't the first pass of the OnTick function of both EA's be where this difference due to variable allocation/deallocation happen? Why is this only reflected on the start of second pass of the OnTick function for both EAs? My theory must be incorrect,

Alain Verleyen
39060
Alain Verleyen  
nadiawicket:

Looks like its just the variable allocation on the first pass of the OnTick where we need to read whats below property strict, unlike in subsequent passes of the OnTick.  This explains why its normalized to 60000 microseconds after the first pass on both EA's. Weird thing is that this should affect the exact first pass, not second pass and after.

FirstEA:


Second

EA


You just skip allocation of variables on the first pass if you declare inside OnTick to the best of my understanding. Why then the first pass is the same for both? Shouldn't the first pass of the OnTick function of both EA's be where this difference due to variable allocation/deallocation happen? Why is this only reflected on the start of second pass of the OnTick function for both EAs? My theory must be incorrect,

You are misreading your log. What you highlighted is the time between 2 ticks, not the processing time of 1 tick.

Anyway, you can't measure things this way and believe you will be able to compare. You are measuring here more the tester and print statement than anything else.

nadiawicket
965
nadiawicket  
Alain Verleyen:

You are misreading your log. What you highlighted is the time between 2 ticks, not the processing time of 1 tick.

Anyway, you can't measure things this way and believe you will be able to compare. You are measuring here more the tester and print statement than anything else.

Any real/significant benefit at all with the second EA's style of handling variables compared to the first?

What accounts for that discrepancy in time highlighted in red when comparing one EA to the other? Why is the first one 1700309 and the second only 578192?

Every time I run the same EA on the same date on the MT4 strategy tester, I get the exact same ticks at the exact same time according to microsecond count.

Why does this tick dispensation time get altered according to microsecond count when running these 2 different EA's? Shouldn't ticks be coming in at the same exact time?

Reason for all of this is that I'm trying to discover why I see many of the more experienced looking programmers who post MQL4 code online declare everything that is not an external variable inside the OnTick function instead of up top below property strict. Is there any real benefit to declaring variables only once inside the OnTick than to declaring them on Top and then actual assigning values inside  on Tick for whatever we will do with them?

Seems its more efficient as only one declaration instead of 2 is faster and then maybe this "redeclaration" every OnTick/this single declaration and assignment in the same line just OnTick approach like this might also have other benefits that any MQL4 programmer would like to know about. I attempted to illustrate this difference in coding style in 2 the different EA's I posted; where the second one looks more like how the more experienced looking programmers handle these types of variables compared to the first one which is how I currently handle variables.

Seng Joo Thio
1135
Seng Joo Thio  
nadiawicket:

Any real/significant benefit at all with the second EA's style of handling variables compared to the first?

What accounts for that discrepancy in time highlighted in red when comparing one EA to the other? Why is the first one 1700309 and the second only 578192?

Every time I run the same EA on the same date on the MT4 strategy tester, I get the exact same ticks at the exact same time according to microsecond count.

Why does this tick dispensation time get altered according to microsecond count when running these 2 different EA's? Shouldn't ticks be coming in at the same exact time?

Reason for all of this is that I'm trying to discover why I see many of the more experienced looking programmers who post MQL4 code online declare everything that is not an external variable inside the OnTick function instead of up top below property strict. Is there any real benefit to declaring variables only once inside the OnTick than to declaring them on Top and then actual assigning values inside  on Tick for whatever we will do with them?

Seems its more efficient as only one declaration instead of 2 is faster and then maybe this "redeclaration" every OnTick/this single declaration and assignment in the same line just OnTick approach like this might also have other benefits that any MQL4 programmer would like to know about. I attempted to illustrate this difference in coding style in 2 the different EA's I posted; where the second one looks more like how the more experienced looking programmers handle these types of variables compared to the first one which is how I currently handle variables.

I ran your codes, and the one with local declarations took more time than the other:

2019.09.18 09:46:19.725 2019.09.17 00:01:08  globalvariable AUDCAD,M1: 198155
2019.09.18 09:46:19.725 2019.09.17 00:01:08  globalvariable AUDCAD,M1: whatever232121.123whatever20.90888
2019.09.18 09:46:19.725 2019.09.17 00:01:08  globalvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:46:19.725 2019.09.17 00:01:08  globalvariable AUDCAD,M1: Greater
2019.09.18 09:46:19.725 2019.09.17 00:01:08  globalvariable AUDCAD,M1: 198120
2019.09.18 09:46:19.659 2019.09.17 00:01:00  globalvariable AUDCAD,M1: 132163
2019.09.18 09:46:19.659 2019.09.17 00:01:00  globalvariable AUDCAD,M1: whatever232121.123whatever20.9088900000000001
2019.09.18 09:46:19.659 2019.09.17 00:01:00  globalvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:46:19.659 2019.09.17 00:01:00  globalvariable AUDCAD,M1: Greater
2019.09.18 09:46:19.659 2019.09.17 00:01:00  globalvariable AUDCAD,M1: 132133
2019.09.18 09:46:19.593 2019.09.17 00:00:59  globalvariable AUDCAD,M1: 66186
2019.09.18 09:46:19.593 2019.09.17 00:00:59  globalvariable AUDCAD,M1: whatever232121.123whatever20.90886
2019.09.18 09:46:19.593 2019.09.17 00:00:59  globalvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:46:19.593 2019.09.17 00:00:59  globalvariable AUDCAD,M1: Greater
2019.09.18 09:46:19.593 2019.09.17 00:00:59  globalvariable AUDCAD,M1: 66151
2019.09.18 09:46:19.527 2019.09.17 00:00:00  globalvariable AUDCAD,M1: 414
2019.09.18 09:46:19.527 2019.09.17 00:00:00  globalvariable AUDCAD,M1: whatever232121.123whatever20.9086200000000001
2019.09.18 09:46:19.527 2019.09.17 00:00:00  globalvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:46:19.527 2019.09.17 00:00:00  globalvariable AUDCAD,M1: Greater
2019.09.18 09:46:19.527 2019.09.17 00:00:00  globalvariable AUDCAD,M1: 344

and

2019.09.18 09:50:42.410 2019.09.17 00:01:08  localvariable AUDCAD,M1: 593691
2019.09.18 09:50:42.410 2019.09.17 00:01:08  localvariable AUDCAD,M1: whatever232121.123whatever20.90888
2019.09.18 09:50:42.410 2019.09.17 00:01:08  localvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:50:42.410 2019.09.17 00:01:08  localvariable AUDCAD,M1: Greater
2019.09.18 09:50:42.410 2019.09.17 00:01:08  localvariable AUDCAD,M1: 593651
2019.09.18 09:50:42.212 2019.09.17 00:01:00  localvariable AUDCAD,M1: 395702
2019.09.18 09:50:42.212 2019.09.17 00:01:00  localvariable AUDCAD,M1: whatever232121.123whatever20.9088900000000001
2019.09.18 09:50:42.212 2019.09.17 00:01:00  localvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:50:42.212 2019.09.17 00:01:00  localvariable AUDCAD,M1: Greater
2019.09.18 09:50:42.212 2019.09.17 00:01:00  localvariable AUDCAD,M1: 395674
2019.09.18 09:50:42.014 2019.09.17 00:00:59  localvariable AUDCAD,M1: 197756
2019.09.18 09:50:42.014 2019.09.17 00:00:59  localvariable AUDCAD,M1: whatever232121.123whatever20.90886
2019.09.18 09:50:42.014 2019.09.17 00:00:59  localvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:50:42.014 2019.09.17 00:00:59  localvariable AUDCAD,M1: Greater
2019.09.18 09:50:42.014 2019.09.17 00:00:59  localvariable AUDCAD,M1: 197727
2019.09.18 09:50:41.816 2019.09.17 00:00:00  localvariable AUDCAD,M1: 389
2019.09.18 09:50:41.816 2019.09.17 00:00:00  localvariable AUDCAD,M1: whatever232121.123whatever20.9086200000000001
2019.09.18 09:50:41.816 2019.09.17 00:00:00  localvariable AUDCAD,M1: whatever232121.123
2019.09.18 09:50:41.816 2019.09.17 00:00:00  localvariable AUDCAD,M1: Greater
2019.09.18 09:50:41.816 2019.09.17 00:00:00  localvariable AUDCAD,M1: 327
2019.09.18 09:50:41.791 2019.09.17 00:00:00  localvariable test started

Conclusion? I think all these time tests point to one thing: that you won't get anything conclusive 

As to the pros and cons of declaring variables globally or locally - it really depends on usage and ease in debugging. It is good practice to declare variables within the scope that you use them, so as to avoid unnecessary/unexpected conflicts - that explains why good/experienced programmers tend to declare variables locally.

nadiawicket
965
nadiawicket  
Seng Joo Thio:

I ran your codes, and the one with local declarations took more time than the other:

and

Conclusion? I think all these time tests point to one thing: that you won't get anything conclusive 

As to the pros and cons of declaring variables globally or locally - it really depends on usage and ease in debugging. It is good practice to declare variables within the scope that you use them, so as to avoid unnecessary/unexpected conflicts - that explains why good/experienced programmers tend to declare variables locally.

Really appreciate you running those tests and taking the time to read these posts. Real cash on the line so can't really have too much info at this moment.

Any insight into what such conflicts can be avoided, or any more insight into why the discrepancy, PC load, whatever, especially from someone with experience on Live is extremely valuable and more than welcome.

I would've never suspected *meaningless random clock jitter* to be the cause of this discrepancy
12
To add comments, please log in or register