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

 
Maxim Kuznetsov #:

double-click highlights a word, tripple-click a logical expression. triple-click doesn't always work for everyone....

but you can practice it on this text.

It would be good to read the whole text to the end

Forum on trading, automated trading systems and testing trading strategies.

Peculiarities of mql5 language, subtleties and techniques of work

Alexey Viktorov, 2024.02.18 14:49

It is not the first time I notice that at the "numerous" requests of users do something and immediately break something. It was always CTRL+click to highlight a word. For me it is easier than double click, because the load on the index finger and without double clicks is quite great. Sometimes it even hurts in the evening. Now it works like this, and then like they've made it new. You don't know when it's supposed to work.


 
Nikolai Semko #:
Have you ever used Vim?

I don't know what it is. In ME I use the mouse only when I need to switch to a tab of some open file and disable/enable compiler optimisation. I don't use the mouse anymore, the hotkeys are enough.

 
Defining the compiler optimisation setting.
// true - оптимизация компилятора включена, false - выключена.
bool IsOptimizationCompiler( void )
{
  static ulong PrevValue = INT_MAX;

  if (PrevValue == INT_MAX)
  {
    const ulong StartTime = GetMicrosecondCount();
    
    for (int i = 0; i < 1 e5; i++)
      const double j = MathSin(0);
      
    PrevValue = GetMicrosecondCount() - StartTime;
  }
  
  return(PrevValue < 5);  
}
 
fxsaber #:
Defining the compiler optimisation setting.

useful for what?!

 
amrali #:

For what?!

Forum on trading, automated trading systems and testing trading strategies

Errors, bugs, questions

fxsaber, 2024.03.05 16:01

The Expert Advisor outputs stat. data of the speed of heavy calculations. Sometimes I see that they are slow. I don't immediately realise that EX5 without optimisation enabled. I would like to be able to print this compiler flag, as is done with _RELEASE and __CPU_ARCHITECTURE__.

Calculate Time (2024.02.27 00:00:00 - 2024.03.05 17:23:48, 122017 ticks) = 21 ms. (5810333 ticks/sec) X64 Regular Release, Optimization compiler = true
Calculate Time (2024.02.27 00:00:00 - 2024.03.05 17:24:26, 122043 ticks) = 46 ms. (2653108 ticks/sec) X64 Regular Release, Optimization compiler = false
 

In monosymbolic Expert Advisors it is obvious that for performance in Tester you have to give up using PositionGetString and OrderGetString.

In multi-currency Expert Advisors it can also be done. For example, through Magic. Then you can get a noticeable effect.

 
Here is such an unexpected result of the for.

Forum on trading, automated trading systems and testing trading strategies.

New version of MetaTrader 5 build 4230: more built-in applications and expanded ONNX support

fxsaber, 2024.03.19 20:48

    for (uint i = Amount; (bool)i--;)
//    for (int i = 0; i < Amount; i++) // Почему-то ускоряет выполнение.

For some reason the classic is faster.

 
fxsaber #:
This is the unexpected result of the for loop.

For some reason, the classic is faster.

Demonstration of a huge difference in the performance of two types of for loops.

input datetime inFrom = D'2023.01.01';

class TICKS_ARRAY
{
public:
  MqlTick Ticks[];
};

template <typename T>
long GetSum( const T &TicksArray[] )
{
  const int Amount = ::ArraySize(TicksArray);

  int Count = 0;
  
  int Size[];
  bool Res[];
  int Pos[];

  ::ArrayResize(Pos, Amount);
  ::ArrayInitialize(Pos, 0);

  long Tmp = 0;
      
  for (uint i = ::ArrayResize(Res, ::ArrayResize(Size, Amount)); (bool)i--;)
  {
    Size[i] = ::ArraySize(TicksArray[i].Ticks);
    
    if (Res[i] = Size[i])
      Count++;
  }
 
  while (Count)
  {
    MqlTick MinTick = {0, 0, 0, 0, 0, LONG_MAX};
    uint Index;
      
    // https://www.mql5.com/ru/forum/462835/page24#comment_52772777
    for (uint i = Amount; (bool)i--;)
//    for (int i = 0; i < Amount; i++)
      if (Res[i])
      {
        // Количество вызовов в ~(1+Amount)/2 раз больше общего числа элементов.
        const MqlTick Tick = TicksArray[i].Ticks[Pos[i]];
        
        if (Tick.time_msc < MinTick.time_msc)
        {
          MinTick = Tick;
          
          Index = i;
        }
      }
      
    if (!(Res[Index] = (++Pos[Index] != Size[Index])))
      Count--;
      
    Tmp += MinTick.time_msc;
  }
    
  return(Tmp);
}

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

void OnStart()
{
  const string Symbols[] = {"EURUSD", "GBPUSD", "AUDUSD"};
  
  TICKS_ARRAY TicksArray[];
  
  const int Size = ::ArrayResize(TicksArray, ::ArraySize(Symbols));

  for (int i = 0; i < Size; i++)
    Print(CopyTicksRange(Symbols[i], TicksArray[i].Ticks, COPY_TICKS_ALL, inFrom * 1000));    

  _B(GetSum(TicksArray), 1);
  _B(GetSum(TicksArray), 1); // Замедляет выполнение предыдущей строки!
}


Two types of loops are highlighted in the code. Replace one with the other to see the effect.


for (int i = 0; i < Amount; i++)

20114034
23551872
23095650
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 76 in OnStart: GetSum(TicksArray)] = 1137474 mcs.
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 77 in OnStart: GetSum(TicksArray)] = 1141950 mcs.


for (uint i = Amount; (bool)i--;)

20114088
23551872
23095650
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 76 in OnStart: GetSum(TicksArray)] = 1672893 mcs.
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 77 in OnStart: GetSum(TicksArray)] = 1684673 mcs.


The difference is almost 1.5 times!


The reason.

Forum on trading, automated trading systems and testing trading strategies.

New version of MetaTrader 5 build 4230: more built-in applications and expanded ONNX support

Renat Fatkhullin, 2024.03.20 02:21

Don't use hacker methods in for loops - this way you spoil the loop/vectorisation optimisation pattern for the compiler and get worse code in working conditions. At the same time you should take into account that there is a considerable chance of self-deception on truncated synthetic benchmarks where some hacker methods may show fake improvement.


ZY

for (int i = Amount - 1; i >= 0; i--)

20114356
23553353
23096711
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 77 in OnStart: GetSum(TicksArray)] = 1144988 mcs.
Alert: Bench_Stack = 0, 1 <= Time[Test9.mq5 78 in OnStart: GetSum(TicksArray)] = 1150288 mcs.

This variant seems to be a classic too - it doesn't slow down.

 
fxsaber #

How about this?

for (uint i = Amount; i-- >= 0;)
 
trader6_1 #:

How about this?

Going outside the array. Or, if Amount already takes into account (size - 1), it should not make any difference: for (int i = Amount - 1; i >= 0; i--))