Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 53

 
Çok sayıda dizi nasıl hızlı bir şekilde eklenir (örneğin, dizide bir ticaret raporu oluşturun)
 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)); // Почему эта строка всегда выполняется заметно быстрее, чем предыдущая?
}

Sonuç

 2748404
12678
10388

250 kat daha hızlı ve bu sınır değil!


Tehdit Kırmızısı, açıklanamayacak bir gerçeğe işaret etti.

 
fxsaber :
Çok sayıda dizi nasıl hızlı bir şekilde eklenir (örneğin, dizide bir ticaret raporu oluşturun)

Sonuç

250 kat daha hızlı ve bu sınır değil!


Tehdit Kırmızı, açıklanamayacak bir gerçeğe işaret etti.

Bellek havuzunun özellikleri, SumString2 bellek havuzuna ilk kez çağrıldığında, sistemden gelen belleğe "doyur" ve bir dahaki sefere bellek artık sistemden talep edilmez.

SumString1'i düzeltmenizi öneririm

 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);
}
 
İlyas :

Bellek havuzunun özellikleri, SumString2 bellek havuzuna ilk kez çağrıldığında, sistemden gelen belleğe "doyur" ve bir dahaki sefere bellek artık sistemden talep edilmez.

SumString1'i düzeltmenizi öneririm

Teşekkür ederim! Alma arabelleği kavramını en azından bir şekilde Yardım'a yansıtabilir misiniz? Şu anda sadece açıklaması net olmayan StringBufferLen var.

 
fxsaber :

Teşekkür ederim! Alma arabelleği kavramını en azından bir şekilde Yardım'a yansıtabilir misiniz? Şimdi, açıklamasından hiçbir şeyin net olmadığı yalnızca StringBufferLen var.

Duc açık görünüyor, bir dize için ayrılmış bellekten bahsediyoruz. Sadece Ilya bir şekilde "sistemden bellekle doygunluk" hakkında kafa karıştırıcı bir şekilde açıklıyor)

Bu arada, yerel bir değişkenin daha önce ayrılmış belleği kullanması gibi bir özellikten de haberim yoktu. Dolayısıyla, tek seferlik ağır bir hesaplamadan bahsetmediğimiz sürece, kendi optimizasyonunuzu eskrim altına almanın pek bir anlamı olmadığı ortaya çıkıyor. Eh, bu hafızayı serbest bırakma sorunu da belirsiz. Program yürütme sırasında mı yoksa yalnızca başlatmadan kaldırma sırasında mı serbest bırakılır?

 
Alexey Navoykov :

Duc açık görünüyor, bir dize için ayrılmış bellekten bahsediyoruz. Sadece Ilya bir şekilde "sistemden bellekle doygunluk" hakkında kafa karıştırıcı bir şekilde açıklıyor)

Tabii ki İlya'nın kodu ne zaman getirdiği belli oluyor. Ne yazık ki, Yardım'da bundan bahsedilmiyor.

Bu arada, yerel bir değişkenin daha önce ayrılmış belleği kullanması gibi bir özellikten de haberim yoktu. Dolayısıyla, tek seferlik ağır bir hesaplamadan bahsetmediğimiz sürece, kendi optimizasyonunuzu eskrim altına almanın pek bir anlamı olmadığı ortaya çıkıyor.

Az önce öyle bir durumla karşılaştım ki bir dizi oluşturmak saniyeler aldı. Ve optimizasyondan sonra - milisaniye. Ancak İlya'nın seçeneği elbette en hızlısı. Yardım mükemmel olsaydı, elbette esnetmezdim.

 
fxsaber :

Tabii ki İlya'nın kodu ne zaman getirdiği belli oluyor. Ne yazık ki, Yardım'da bundan bahsedilmiyor.

Az önce öyle bir durumla karşılaştım ki bir dizi oluşturmak saniyeler aldı. Ve optimizasyondan sonra - milisaniye. Ancak İlya'nın seçeneği elbette en hızlısı. Yardım mükemmel olsaydı, elbette çit çekmezdim.

Eh, StringInit ile ilgili olarak, uzun zamandır biliniyor gibi görünüyor. Ayrıca her zaman büyük hacimlerde kullanırım. Eklenecek satırların tam uzunluğunu bilmiyorsam, yaklaşık olarak alırım.

 

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Kitaplıklar: TesterBenchmark

fxsaber , 2017.08.15 19:31

ZY2 Ve her paketin ilk geçişinde 1648'deki bu frenler nelerdir? 1643 yılında

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri

fxsaber , 2017.08.15 17:16

Bir toplu Ajan görevinin ilk geçişinde (örneğin, tek bir test cihazı çalıştırması sırasında), Expert Advisor'ın başlatılması ile ilk NewTick olayı arasındaki süre birkaç saniye sürebilir. Paketin sonraki geçişlerinde bu süre sıfırdır.

Sanki 1648'de test cihazı hemen bir NewTick olayı başlatır. Hangi, elbette, yanlış.
 

Test cihazında IsStopped() her zaman sıfır döndürür ( false değil ). Bu nedenle, gerçek hayatta olduğu gibi bu bayrağın ExpertRemove() ile etkileşimine güvenmek test cihazında hatalıdır.

 
StringInit (Str);
Str = NULL ;

İlk satır, aynı sonuçla ikinci satırdan daha hızlıdır.

 

Ticaret, otomatik ticaret sistemleri ve ticaret stratejilerinin test edilmesi hakkında forum

Kitaplıklar: TesterBenchmark

fxsaber , 2017.09.05 09:36

PositionSelect'i aptalca PositionGetTicket ile değiştirmek, geriye dönük test hızını %7 artırır!

Ve bu bir netleştirme hesabında!