Features of the mql5 language, subtleties and tricks - page 49

 
fxsaber:

If you press TAB right after the words if, else, while, for, do, there will be a little extra construction...


Geez... cool, after 5 years of knowing mql - I found it out.

 

Conclusions from a conversation in SD about one problem raised.

It turns out that assigning a value to a string variable is a VERY expensive operation.

So expensive that it is desirable to avoid it if possible, until the developers improve this point in the compiler, which does not seem to happen soon.


As an example, if you run a real tick run for a month on FIBO, it will be about 1 million ticks. If you get the value of PositionGetString on each tick and compare it to something, the performance would be acceptable, but if you assign the result of the function to a string variable first and then compare it before the comparison, the run duration would increase by about a second.


If it seems to be a trifle, it is an erroneous view. When such an EA is run in optimization mode for several thousand passes, that extra second will result in additional hours of waiting. I.e. a harmless string assignment may cause additional hours of waiting during optimization. Be careful and take this nuance into account.


There is a small tool in kodobase that allows you to detect such failures in different implementations of the same trading logic. Write a fast code.

 
fxsaber:

Conclusions from a conversation in SD about one problem raised.

It turns out that assigning a value to a string variable is a VERY expensive operation.

So expensive that it is desirable to avoid it if possible, until the developers improve this point in the compiler, which does not seem to happen soon.


As an example, if you run a real tick run for a month on FIBO, it will be about 1 million ticks. If you get the value of PositionGetString on each tick and compare it to something, the performance would be acceptable, but if you assign the result of the function to a string variable first and then compare it before the comparison, the run duration would increase by about a second.


If it seems to be a trifle, it is an erroneous view. When such an EA is run in optimization mode for several thousand passes, that extra second will result in additional hours of waiting. I.e. a harmless string assignment may cause additional hours of waiting during optimization. Be careful and take this nuance into account.


In kodobase, there is a small tool that allows you to detect such failures in different implementations of the same trading logic. Write a quick code.

Thank you, I didn't think it was possible. I will take it into account in future developments

 

A simple bedtime riddle, why the yellow results?

struct INT
{
  int Array[];
  
  INT()
  {
    Print(__FUNCTION__); // до сюда не дойдет
  }
};

void OnStart()
{
  INT i = {0};
  
  Print(ArrayResize(i.Array, 5)); // -1
}
 
fxsaber:

A simple bedtime riddle, why the yellow results?

Because the structure is packed with zeros, not by constructor, that's why the array structure is initialized incorrectly, arrayresize doesn't like such arrays, my code crashed on such resizing.
 
Combinator:
Because the structure is packed with zeros, not the constructor, that's why the array structure is initialized incorrectly, arrayresize doesn't like such arrays, my code crashed on such resize at all.

It's good that everyone knows about it.

 
Slava:

What is meant by GetMicrosecondCount. It is impossible to say for sure if it slows down the server. It may have an indirect effect. Therefore, it is better to use the system's native GetTickCount

GetMicrosecondCount is used to measure short code execution times. To measure the number of times OnTick was executed, it is better to use GetTickCount.

Try to use GetMicrosecondsCount instead of GetTickCount once you get stable results. You will tell me about it here. Maybe I am worrying about it too much.

Your hypothesis turned out to be correct, multiple calls to GetMicrosecondsCount cause terrible lags in the tester. However, GetTickCount has the same effect.
 
fxsaber:

Conclusions from a conversation in SD about one problem raised.

It turns out that assigning a value to a string variable is a VERY expensive operation.

So expensive that it is desirable to avoid it if possible, until the developers improve this point in the compiler, which does not seem to happen soon.


As an example, if you run a real tick run for a month on FIBO, it will be about 1 million ticks. If you get the value of PositionGetString on each tick and compare it to something, the performance would be acceptable, but if you assign the result of the function to a string variable first and then compare it before the comparison, the run duration would increase by about a second.


If it seems to be a trifle, it is an erroneous view. When such an EA is run in optimization mode for several thousand passes, that extra second will result in additional hours of waiting. I.e. a harmless string assignment may cause additional hours of waiting during optimization. Be careful and take this nuance into account.


In kodobase, there is a small tool that allows you to detect such failures in different implementations of the same trading logic. Write a fast code.

struct STRUCT
{
  string Str;
  
  string Get() const { return(this.Str); }
};

void OnStart()
{
  STRUCT Struct;
  
  Print(Struct.Str);
  Print(Struct.Get()); // Выполняется гораздо дольше, чем предыдущая строка
}
 
fxsaber:

It turns out that assigning a value to a string variable is a VERY expensive operation.

...

If you first assign the result of a function to a string variable before comparing, and then compare it, it will increase the run time by about a second.

As I see it, the problem isn't so much with the high cost of the assignment, but with the fact that the compiler doesn't cut this unnecessary assignment out of the code for some reason, even though it should. That is, the compiled code should be the same in both cases.
 
Alexey Navoykov:
As far as I understand, the problem is not so much in expensive assignment, but in the fact that the compiler for some reason doesn't cut this unnecessary assignment from the code, though it should. That is, compiled code should be the same in both cases.

This is a minor problem. Yes, the compiler optimizer does not yet know how to optimize such string moments. But it is in the string assignment where the slowdown problem lies.

Write code that cannot be optimized by the compiler, but at the same time make assignments in it. And you will see the lags.

The example of reading of a string-field of a structure through a function is exactly the way the reading of position properties is implemented in MT4/5.

In MT4, the same OrderSymbol() is braking if it is implemented in MT5. The developers themselves try to pass to their functions strings via links.

Therefore, if you write something like this

if ((OrderSymbol() == Symb) && (OrderMagicNumber == Magic))

it's always better to put OrderSymbol-condition at the end of general condition.


In general, I see distinct slowdowns at seemingly smooth surface when I use TesterBench.

Reason: