mql5语言的特点、微妙之处以及技巧 - 页 53

 
如何快速添加许多字符串(如用字符串生成交易报告)。
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)); // Почему эта строка всегда выполняется заметно быстрее, чем предыдущая?
}

结果

2748404
12678
10388

250倍的速度,而这还不是极限!


HH 用红色标记的事实不能以任何方式解释。

 
fxsaber:
如何快速地把许多字符串加起来(如用字符串生成交易报告)。

结果

250倍的速度,而这还不是极限!


ZS红色标志着一个无法用任何方式解释的事实。

内存池的特殊性,当SumString2第一次被调用时,内存池被系统的内存 "饱和 "了,当你再次调用时,不再向系统申请内存。

我建议纠正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:

内存池很特别,SumString2第一次被调用到内存池时,它被系统的内存 "饱和 "了,第二次就不会再向系统请求内存。

我建议纠正SumString1

谢谢你!你能不能在帮助中至少反映一下接收缓冲区的概念。现在只有StringBufferLen,它的描述并没有说明什么。

 
fxsaber:

谢谢你!能否请你在帮助中至少解释一下接收缓冲区的概念。现在只有StringBufferLen,这个描述没有任何意义。

这很清楚,我们在谈论的是为串联分配的内存。只是Elijah对 "来自系统的内存饱和度 "的解释在某种程度上令人困惑)

顺便说一下,我也不知道有这样的功能,即局部变量 使用以前分配的内存。因此,事实证明,自己做优化没有什么意义,除非我们谈论的是单一的重度计算。释放这种记忆的问题也不清楚。它是在运行时释放还是只在脱机时释放?

 
阿列克谢-纳沃伊科夫

很明显,我们谈论的是为字符串分配的内存。只是伊利亚以一种非常复杂的方式解释了 "来自系统的内存饱和"。)

当然,当伊利亚引用代码的时候,这也是可以理解的。不幸的是,他在《帮助》中只字未提此事。

顺便说一下,我也不知道这个具体的功能:局部变量 使用先前分配的内存。因此,事实证明,除非我们处理单一的重型计算,否则创建自己的优化没有什么意义。

我刚刚遇到了这样的情况,我花了几秒钟才形成一个字符串。但在优化之后,我花了几毫秒的时间。但伊利亚的变体当然是最快的。如果我的帮助是完美的,我就不会把它变成这样。

 
fxsaber:

当然,当伊利亚给出密码时,这也是可以理解的。不幸的是,在《帮助》中没有关于它的消息。

我刚刚遇到了这样一个案例,当时花了几秒钟才形成一个字符串。但经过优化后,它是在几毫秒内完成的。但伊利亚的变体当然是最快的。如果我们的帮助是理想的,我就不会让它变成这样。

好吧,说到StringInit,它已经被知道很久了。我也总是用它来处理大量的事情。如果我不知道要加的线的确切长度,我就用大概的长度。

 

关于交易、自动交易系统和策略测试的论坛

图书馆:TesterBenchmark

fxsaber, 2017.08.15 19:31

ZS2 在1648年,每包的第一遍的刹车是怎么回事?1643年,情况是这样 的。

关于交易、自动交易系统和交易策略测试的论坛

mql5语言的特点、微妙之处以及技巧

fxsaber, 2017.08.15 17:16

在代理工作捆绑的第一遍(如单一测试员运行),从EA运行到第一个NewTick事件之间的时间可能需要几秒钟。在随后的背包传递中,这个时间是零。

就像在1648年,测试者立即做出一个NewTick事件。当然,这是不对的。
 

在测试器中,IsStopped()总是返回0(不是假的)。因此,期望这个标志与ExpertRemove()互动 是错误的,就像现实世界中的测试员一样。

 
StringInit(Str);
Str = NULL;

第一行的运行速度比第二行快,结果相同。

 

关于交易、自动交易系统和策略测试的论坛

图书馆:TesterBenchmark

fxsaber, 2017.09.05 09:36

愚蠢地用PositionGetTicket代替PositionSelect,使回测速度提高了7%!

而这是在净值账户上!