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

 
How to quickly add up many strings (e.g., generate a trade report in string)
class SUM_STRING
{
protected:
  uchar Data[];
    
public:
  SUM_STRING( const int Reserve = 0 )
  {
    ::ArrayResize(this.Data, 1, Reserve);
  }

  void operator +=( const string Str )
  {
    ::StringToCharArray(Str, this.Data, ::ArraySize(this.Data) - 1);
  }
  
  const string Get( void ) const
  {
    return(::CharArrayToString(this.Data));
  }
};

// Классическое складывание
ulong SumString1( string TmpStr, const int Amount )
{
  const ulong StartTime = GetMicrosecondCount();

  string Str = "";

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

  return(GetMicrosecondCount() - StartTime);
}

// Быстрое складывание
ulong SumString2( string TmpStr, const int Amount )
{
  const ulong StartTime = GetMicrosecondCount();

  SUM_STRING SumStr(Amount * StringLen(TmpStr) + 1);

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

  const string Str = SumStr.Get();

  return(GetMicrosecondCount() - StartTime);
}

// #property script_show_inputs

input int inLen = 400;    // Длина строки, которую будем добавлять
input int inAmount = 1 e4; // Сколько раз будем складывать

// Как быстро сложить много строк (например, сгенерировать торговый отчет в string)
void OnStart()
{  
  string Str;
  
  StringInit(Str, inLen, 1);
  
  Print(SumString1(Str, inAmount)); // Время классического решения
  Print(SumString2(Str, inAmount)); // Время альтернативного решения
  Print(SumString2(Str, inAmount)); // Почему эта строка всегда выполняется заметно быстрее, чем предыдущая?
}

The result

2748404
12678
10388

250 times faster and that's not the limit!


SZY Red marked fact, which can not explain in any way.

 
fxsaber:
How to quickly add up many strings (e.g. generate a trade report in string)

The result

250 times faster and that's not the limit!


SZZ The fact marked in red cannot be explained in any way.

The peculiarity of the memory pool, the first call SumString2 in the memory pool is "saturated" with memory from the system, the second time, the memory is no longer requested from the system.

I recommend correcting SumString1.

ulong SumString1( string TmpStr, const int Amount )
{
  const ulong StartTime = GetMicrosecondCount();

  string Str;
  StringInit(Str,Amount * StringLen(TmpStr) + 1);            << обеспечим строке приёмный буфер

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

  return(GetMicrosecondCount() - StartTime);
}
 
Ilyas:

The peculiarities of the memory pool, when SumString2 is called for the first time, the memory pool is "saturated" with memory from the system, when it is called again, the memory is no longer requested from the system.

I recommend correcting SumString1.

Thank you! Could you reflect the notion of a receive buffer somehow in the Help. Right now there is onlyStringBufferLen which description doesn't make any sense.

 
fxsaber:

Thank you! Could you describe the concept of a receive buffer somehow in Help. Right now there is only StringBufferLen, which description doesn't make any sense.

Everything is clear, we are talking about memory allocated for stringing. It's just that Ilya explains "saturation with memory from the system" in a very fuzzy way. )

By the way, I also didn't know about such feature, that a local variable uses previously allocated memory. So it turns out that there's not much point in making your own optimization, unless we're talking about a single heavy calculation. The issue of releasing this memory is also unclear. Is it freed during runtime or only during deinitialization?

 
Alexey Navoykov:

It seems to be clear, we are talking about the allocated memory for the string. It's just that Ilya is a bit confusing when it comes to "memory saturation from the system". )

Of course, it's understandable when Ilya has cited a code. In Help, unfortunately, not a word about it.

By the way, I also did not know about such a feature, which is that a local variable uses memory, previously allocated. So it turns out that there is not much sense in creating your own optimization unless we are talking about a single heavy calculation.

I just encountered such a case when it took seconds to form a string. After optimization it took me milliseconds. But Ilya's variant is, of course, the fastest. Of course, if Help was perfect, I wouldn't have made such a fuss.

 
fxsaber:

Of course, it is clear when Ilya gave the code. In the Help, unfortunately, not a word about it.

I had just come across a case when it took seconds to form a string. After optimization it was done in milliseconds. However, Ilya's variant is, of course, the fastest. If our Help was perfect, I certainly would not have made it so.

Well, speaking of StringInit, it has long been known about it. I always use it for large volumes too. If I don't know exact length of lines to be added, I use approximate length.

 

Forum on trading, automated trading systems and testing trading strategies

Libraries: TesterBenchmark

fxsaber, 2017.08.15 19:31

ZS2 What's with the brakes in 1648 on the first pass of each pack? In 1643 it was like this.

Forum on trading, automated trading systems and testing trading strategies

Features of mql5 language, subtleties and tricks

fxsaber, 2017.08.15 17:16

On the first pass of an Agent job pack (e.g., a single tester run), the time between the EA running and the first NewTick event can take several seconds. On subsequent passes of the pack, this time is zero.

As if in 1648 the tester immediately makes a NewTick event. Which, of course, is wrong.
 

In the tester, IsStopped() always returns zero(not false). So it is wrong in the tester to count on interaction of this flag with ExpertRemove(), as in the real one.

 
StringInit(Str);
Str = NULL;

The first line runs faster than the second with identical results.

 

Forum on trading, automated trading systems and testing trading strategies

Libraries: TesterBenchmark

fxsaber, 2017.09.05 09:36

Stupidly replacing PositionSelect with PositionGetTicket raises backtest speed by 7%!

And that's on a netting account!