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

 
Alain Verleyen :

Bunu göstermek için kıyaslama kodunu sağlayabilir misiniz?

 #define BENCH(A)                                                              \
{                                                                             \
   const ulong StartTime = GetMicrosecondCount ();                              \
  A;                                                                          \
   Print ( "Time[" + #A + "] = " + ( string )( GetMicrosecondCount () - StartTime)); \
}

double Bench1( const int Size, const string Str )
{
   double Tmp = 0 ;
  
   for ( int i = 0 ; i < Size; i++)
    Tmp += ( double )Str;

   return (Tmp);
}

double Bench2( const int Size, const string Str )
{
   double Tmp = 0 ;;
  
   for ( int i = 0 ; i < Size; i++)
    Tmp += StringToDouble (Str);

   return (Tmp);
}

double Bench3( const int Size, const string Str )
{
   double Tmp = 0 ;
  
   for ( int i = 0 ; i < Size; i++)
    Tmp += StringToDouble2(Str); // https://www.mql5.com/ru/forum/170952/page83#comment_7121066

   return (Tmp);
}

void OnStart ()
{  
   const string Str = "123.456" ;
  
  BENCH( Print (Bench1( 1 e7, Str)));
  BENCH( Print (Bench2( 1 e7, Str)));
  BENCH( Print (Bench3( 1 e7, Str)));
}


Sonuç ( Yayın )

 1234559999.924436
Time [ Print (Bench1( 1 e7,Str))] = 1656182
1234559999.924436
Time [ Print (Bench2( 1 e7,Str))] = 1639179
1234559999.924436
Time [ Print (Bench3( 1 e7,Str))] = 147382


PS Profil oluşturma modunda çalıştırırsanız olan budur

 1234559999.924436
Time [ Print (Bench1( 1 e7,Str))] = 1757705
1234559999.924436
Time [ Print (Bench2( 1 e7,Str))] = 1877177
1234559999.924436
Time [ Print (Bench3( 1 e7,Str))] = 4578266

Ne yazık ki, bu durumda profil oluşturucuya güvenilemez.

 
fxsaber :


Sonuç ( Yayın )


PS Profil oluşturma modunda çalıştırırsanız olan budur

Sadece bu değil, bu durumda profil oluşturucuya güvenemezsiniz, Bench1 ayrıca Sürüm sürümünden 10 kat daha hızlı çalışır!

Sayesinde.

Sonuç ( sürüm )

 Time [Bench1( 1 e7,Str)] = 1680754
Time [Bench2( 1 e7,Str)] = 1646789
Time [Bench3( 1 e7,Str)] = 143408     more then 10 times faster !!! 

Bir strateji danışmanı ile test edilmiştir.

2018.04.16 14:24:28.049    Core 1    OnTester result 39725470 (µs bench1)
2018.04.16 14:26:14.629    Core 1    OnTester result 39270950 (µs bench2)
2018.04.16 14:27:13.566    Core 1    OnTester result 20467067 (µs bench3)

2 kat daha hızlı (ancak 10 kattan fazla değil, bu kesinlikle derleyici optimizasyonundan kaynaklanıyor).

Dosyalar:
170952.mq5  6 kb
 
Alain Verleyen :

Bir strateji danışmanı ile test edilmiştir.

2018.04.16 14:24:28.049    Core 1    OnTester result 39725470 (µs bench1)
2018.04.16 14:26:14.629    Core 1    OnTester result 39270950 (µs bench2)
2018.04.16 14:27:13.566    Core 1    OnTester result 20467067 (µs bench3)

2 kat daha hızlı (ancak 10 kattan fazla değil, bu kesinlikle derleyici optimizasyonundan kaynaklanıyor).

Yalnızca OnTick hesaplamasını değil, kene oluşturma süresini de ölçersiniz.

İşte sadece OnTick dondurma

 #define PROFILER_OnTick // Замеряет чистое время выполнения всех OnTick - немного замедляет общую работу
#include <TesterBenchmark.mqh> // https://www.mql5.com/ru/code/18804

input int bench= 1 ; // between 1 and 3

void OnTick ()
{
   static const string Str = "123.456" ;

   switch (bench)
  {
     // https://www.mql5.com/ru/forum/170952/page84#comment_7121207
     case 1 : Bench1( 1 , Str); break ;
     case 2 : Bench2( 1 , Str); break ;
     case 3 : Bench3( 1 , Str); break ;
  }  
}


tezgah1

i = 0 Pass = 0 OnTester = 3.729 s.: OnTick Profiler: Count = 7197033 , Interval = 1.895 s ., 3796990.9 unit/sec , Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent- 127.0 . 0.1 - 3000 build = 1795
i = 1 Pass = 1 OnTester = 3.843 s.: OnTick Profiler: Count = 7197033 , Interval = 1.950 s., 3690523.1 unit/sec , Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent- 127.0 . 0.1 - 3000 build = 1795


tezgah3

i = 0 Pass = 0 OnTester = 2.280 s.: OnTick Profiler: Count = 7197033 , Interval = 0.631 s ., 11404799.6 unit/sec , Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent- 127.0 . 0.1 - 3000 build = 1795
i = 1 Pass = 1 OnTester = 2.340 s.: OnTick Profiler: Count = 7197033 , Interval = 0.640 s., 11242184.6 unit/sec , Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent- 127.0 . 0.1 - 3000 build = 1795


Üç kere. BenchX fonksiyonunun çoklu çağrılması nedeniyle 10 kat hızlanma elde edilmez. StringToDouble2'nin kendisi gerçekten 10 kat daha hızlıdır.

 
fxsaber :

Yalnızca OnTick hesaplamasını değil, kene oluşturma süresini de ölçersiniz.

...

Haklısın.

10 kat daha hızlı olmasına gerçekten şaşırdım, ancak işleviniz yalnızca dizenin geçerli bir çift değer içerdiğini bildiğinizde kullanılabilir.

2018.04.16 17:14:16.183 170952_180416(EURUSD, H1) StringToDouble2(abcdef)=5456784.0

 
Alexey Vyazmikin :

Teşekkürler, ancak bu komut dosyası da yanlış kaydediliyor.

Monitörümde sağ taraftaki kısıtlama dikey bir çizgi ile işaretlenmiş ve ekran bu çizginin çok ötesine geçmiş.

Servis masasından alıntı yapmak için:

Bu durumda ChartScreenShot yardımı tam anlamıyla alınmalıdır.

align_mode=ALIGN_RIGHT

[içinde] Dar ekran görüntüsü çıktı modu. ENUM_ALIGN_MODE numaralandırmasının değeri. ALIGN_RIGHT, sağa hizalama anlamına gelir (sondan çıktı). ALIGN_LEFT, sola hizalamayı belirtir.

Bu, ALIGN_RIGHT hizalaması belirtildiğinde, grafiğin, komutun yürütülmesine eşdeğer olan sağ sınıra kaydırılacağı anlamına gelir.

ChartNavigate(0,CHART_END,0);

Bu davranış, uzun yıllar önce (tarihsel olarak böyle), henüz ChartNavigate () işlevi olmadığında ortaya konmuştu. align_mode=ALIGN_RIGHT ayarının yapılması, grafiğin tam olarak sağ kenarının yakalanmasını sağlamıştır.

Ve ChartNavigate() işlevi eklendiğinde, ChartScreenShot işlevinin davranışı değişmedi.

Bu nedenle, istediğiniz efekti elde etmek istiyorsanız (grafiği sağ kenara kaydırmayın) - align_mode parametresi için ALIGN_LEFT değerini kullanın.

 
Alain Verleyen :

işleviniz yalnızca dizenin geçerli bir çift değer içerdiğini bildiğinizde kullanılabilir.

2018.04.16 17:14:16.183 170952_180416(EURUSD, H1) StringToDouble2(abcdef)=5456784.0

Düzeltildi, şimdi orijinali gibi çalışıyor

 #define PRINT(A) Print ( #A + " = " + ( string )(A))

void OnStart ()
{    
   const string Str[] = { "123.456" , "-asdf1234" , "12as" , ".34 a" , "..23" , "1.." };

   for ( int i = 0 ; i < ArraySize (Str); i++)
  {
    PRINT(Str[i]);
    
    PRINT(( double )Str[i]);
    PRINT(StringToDouble2(Str[i])); // https://www.mql5.com/ru/forum/170952/page83#comment_7121066
    
     Print ( "" );
  }
}
 

Tahsis edilen const'ı kaldırırsanız, işlevin yürütme süresi iki katına çıkar. Bu, derleyicinin her zaman optimal kod üretmediğini ve bu tür ipuçlarına ihtiyaç duyduğunu gösterir.

 
fxsaber :

Tahsis edilen const'ı kaldırırsanız, işlevin yürütme süresi iki katına çıkar. Bu, derleyicinin her zaman optimal kod üretmediğini ve bu tür ipuçlarına ihtiyaç duyduğunu gösterir.

İlginç, teşekkürler.

Lütfen zaten bir cevabınız varken kodunuzu düzenlemeyin, güncellediğiniz bildirimi almadım.

 
fxsaber :

Tahsis edilen const'ı kaldırırsanız, işlevin yürütme süresi iki katına çıkar. Bu, derleyicinin her zaman en uygun kodu üretmediğini ve bu tür ipuçlarına ihtiyaç duyduğunu gösterir.

Çok ilginç...
Bunun neden olduğu hakkında bir fikriniz var mı?

Mekanizma nedir?

 

MQL5 kullanılarak ekrandan alınan ve belirli bir süre boyunca dolu çubuklar içerecek bir ekran görüntüsünün genişliğini belirlemek için aşağıda sunulan çözüm önerilmiştir.

Tuhaflık, grafiğin farklı yaklaşımlarında ekran görüntüsünün genişliğini düzeltmenin gerekli olduğu gerçeği olarak ortaya çıktı.

Ölçekli ve ölçeksiz seçenek için gerçek "katsayıların" (özellikle benim için) farklı olduğu ortaya çıktı.

 if (Use_Shakala== false )
 
 {
   ChartSetInteger ( 0 , CHART_SHOW_PRICE_SCALE , 0 ); //Показывать или нет ценовую шкалу
   int TotalPixel=( int ) ChartGetInteger ( 0 , CHART_WIDTH_IN_PIXELS );   // Ширина графика в пикселях
   int WidthBar= int ( 1 << ChartGetInteger ( 0 , CHART_SCALE ));             // сколько пикселей между барами
   int FirstBar=( int ) ChartGetInteger ( 0 , CHART_FIRST_VISIBLE_BAR );   // номер первого (левого) бара на экране
   int VisibleBars=( int ) ChartGetInteger ( 0 , CHART_VISIBLE_BARS );     // количество видимых баров на экране
   int BarNr= FirstBar-(Shift_Start-Shift_Stop)*(- 1 );               // номер искомого бара, допустим на 12 баров правее самого левого бара 
   int LeftPixelOfBar=((FirstBar-BarNr)>=VisibleBars || FirstBar<BarNr)?(- 1 ):((FirstBar-BarNr)*WidthBar);   // левый пиксель искомого бара, если бара нет на экране тогда -1
   int RightPixelOfBar =(LeftPixelOfBar< 0 )?(- 1 ):LeftPixelOfBar+WidthBar- 1 ;                                 //правый пиксель искомого бара, если бара нет на экране тогда -1
   if (RightPixelOfBar>=TotalPixel) RightPixelOfBar=TotalPixel- 1 ;   // проверяем не за пределами ли экрана 

       if (Zoom== 0 )ZoomX= 6 ;
       if (Zoom== 1 )ZoomX= 5 ;
       if (Zoom== 2 )ZoomX= 5 ;
       if (Zoom== 3 )ZoomX= 4 ;
       if (Zoom== 4 )ZoomX= 2 ;
       if (Zoom== 5 )ZoomX= 0 ;

  pp=WidthBar*((Shift_Start-Shift_Stop)*(- 1 )+ 2 )+ZoomX;
}

   if (Use_Shakala== true )
  {
   ChartSetInteger ( 0 , CHART_SHOW_PRICE_SCALE , 1 ); //Показывать или нет ценовую шкалу
   int TotalPixel=( int ) ChartGetInteger ( 0 , CHART_WIDTH_IN_PIXELS );   // Ширина графика в пикселях
   int WidthBar= int ( 1 << ChartGetInteger ( 0 , CHART_SCALE ));             // сколько пикселей между барами
   int FirstBar=( int ) ChartGetInteger ( 0 , CHART_FIRST_VISIBLE_BAR );   // номер первого (левого) бара на экране
   int VisibleBars=( int ) ChartGetInteger ( 0 , CHART_WIDTH_IN_BARS );     // количество видимых баров на экране
   int BarNr= FirstBar-(Shift_Start-Shift_Stop)*(- 1 );               // номер искомого бара, допустим на 12 баров правее самого левого бара 
   int LeftPixelOfBar=((FirstBar-BarNr)>=VisibleBars || FirstBar<BarNr)?(- 1 ):((FirstBar-BarNr)*WidthBar);   // левый пиксель искомого бара, если бара нет на экране тогда -1
   int RightPixelOfBar =(LeftPixelOfBar< 0 )?(- 1 ):LeftPixelOfBar+WidthBar- 1 ;                                 //правый пиксель искомого бара, если бара нет на экране тогда -1
   if (RightPixelOfBar>=TotalPixel) RightPixelOfBar=TotalPixel- 1 ;   // проверяем не за пределами ли экрана 

       if (Zoom== 0 )ZoomX= 1 ;
       if (Zoom== 1 )ZoomX= 1 ;
       if (Zoom== 2 )ZoomX= 1 ;
       if (Zoom== 3 )ZoomX= 3 ;
       if (Zoom== 4 )ZoomX= 2 ;
       if (Zoom== 5 )ZoomX= 0 ;    
  pp=WidthBar*((Shift_Start-Shift_Stop)*(- 1 )+ 2 - 0.5 )+ZoomX+Schkala;
  
  }
//pp 		 - ширина скриншота
//Shift_Start    - номер левого бара, который целиком должен попасть на скрин
//Shift_Stop     - номер правого бара, который целиком должен попасть на скрин
//Schkala        - ширина цифровой шкалы по методу fxsaber
//Zoom           - степень приближение экрана