Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 236

 
Eine schnellere Implementierung der Standardfunktion PeriodSeconds():
int PeriodSecondsFast(ENUM_TIMEFRAMES tf) {
   return (tf>>14==0)?(tf&0x0FFF)*60:(tf>>14==1)?(tf&0x0FFF)*60*60:(tf>>14==2)?60*60*24*7:2419200;
}

 
Nikolai Semko #:
Eine schnellere Implementierung der Standardfunktion PeriodSeconds():

Ich habe mir das Format angesehen.

template <typename T>
bool IsCorrect( const int Index )
{
  ResetLastError();
  
  return((EnumToString((T)Index) != NULL) && !_LastError);
}

template <typename T>
string ToBits( const T Value )
{
  string Str = NULL;
  
  for(uint i = sizeof(T) << 3; (bool)i--;)
    Str += (string)(int)(!!(Value & (1 << i)));
    
  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 1 e7; i++)
    if (IsCorrect<ENUM_TIMEFRAMES>(i))
      Print(ToBits(i) + " - " + EnumToString((ENUM_TIMEFRAMES)i) + ", " + (string)i);
}
00000000000000000000000000000000 - PERIOD_CURRENT, 0
00000000000000000000000000000001 - PERIOD_M1, 1
00000000000000000000000000000010 - PERIOD_M2, 2
00000000000000000000000000000011 - PERIOD_M3, 3
00000000000000000000000000000100 - PERIOD_M4, 4
00000000000000000000000000000101 - PERIOD_M5, 5
00000000000000000000000000000110 - PERIOD_M6, 6
00000000000000000000000000001010 - PERIOD_M10, 10
00000000000000000000000000001100 - PERIOD_M12, 12
00000000000000000000000000001111 - PERIOD_M15, 15
00000000000000000000000000010100 - PERIOD_M20, 20
00000000000000000000000000011110 - PERIOD_M30, 30
00000000000000000100000000000001 - PERIOD_H1, 16385
00000000000000000100000000000010 - PERIOD_H2, 16386
00000000000000000100000000000011 - PERIOD_H3, 16387
00000000000000000100000000000100 - PERIOD_H4, 16388
00000000000000000100000000000110 - PERIOD_H6, 16390
00000000000000000100000000001000 - PERIOD_H8, 16392
00000000000000000100000000001100 - PERIOD_H12, 16396
00000000000000000100000000011000 - PERIOD_D1, 16408
00000000000000001000000000000001 - PERIOD_W1, 32769
00000000000000001100000000000001 - PERIOD_MN1, 49153

Wahrscheinlich nicht schneller. Ich habe allerdings von der wunderbaren Geschwindigkeit von switch gehört.

int PeriodSecondsFast( const ENUM_TIMEFRAMES tf )
{
  switch (tf)
  {
    case PERIOD_CURRENT: return(PeriodSecondsFast(_Period));      
    case PERIOD_M1:      return(60);
    case PERIOD_M2:      return(120);
    case PERIOD_M3:      return(180);
    case PERIOD_M4:      return(240);
    case PERIOD_M5:      return(300);
    case PERIOD_M6:      return(360);
    case PERIOD_M10:     return(600);
    case PERIOD_M12:     return(720);
    case PERIOD_M15:     return(900);
    case PERIOD_M20:     return(1200);
    case PERIOD_M30:     return(1800);
    case PERIOD_H1:      return(3600);
    case PERIOD_H2:      return(7200);
    case PERIOD_H3:      return(10800);
    case PERIOD_H4:      return(14400);
    case PERIOD_H6:      return(21600);
    case PERIOD_H8:      return(28800);
    case PERIOD_H12:     return(43200);
    case PERIOD_D1:      return(86400);
    case PERIOD_W1:      return(604800);
    case PERIOD_MN1:     return(2592000);
  }
  
  return(0);
}
 
fxsaber #:

Ich habe mir das Format angesehen.

Wahrscheinlich wird es nicht schneller werden. Habe aber von der wundersamen Geschwindigkeit der Umstellung gehört.

Es sieht länger aus, aber ich habe keinen Leistungsunterschied bemerkt.

int PeriodSecondsFast2(ENUM_TIMEFRAMES tf) {
   ushort i_tf= ushort(tf);
   uchar _i =uchar(i_tf>>14);
   int n = i_tf & 0x0FFF;
   switch(_i) {
   case 0: // минуты
      return n*60;
   case 1: // часы
      return n*60*60;
   case 2: // недели
      return 60*60*24*7;
   case 3: // месяцы
      return 2592000;
   }
   return -1;
}

Ich denke also, dass eine einzeilige Version immer noch vorzuziehen ist.

int PeriodSecondsFast(ENUM_TIMEFRAMES tf) {
   return (tf>>14==0)?(tf&0x0FFF)*60:(tf>>14==1)?(tf&0x0FFF)*60*60:(tf>>14==2)?60*60*24*7:60*60*24*30;
}
 
Nikolai Semko #:

sieht länger aus

int PeriodSecondsFast( const ENUM_TIMEFRAMES tf )
{
  static const int Mult[] = {60, 60 * 60, 60 * 60 * 24 * 7, 60 * 60 * 24 * 30};
  
  return((tf & 0xFF) * Mult[tf >> 14]);
}
 

und nun all dies in Matrizen und ONX umzuwandeln :-)

 
fxsaber #:

Ja, das könnte man machen. Besser lesbar.
Leistung auf meinem Laptop ist die gleiche.

 

fxsaber #:

int PeriodSecondsFast( const ENUM_TIMEFRAMES tf )
{
  static const int Mult[] = {60, 60 * 60, 60 * 60 * 24 * 7, 60 * 60 * 24 * 30};
  
  return((tf & 0xFF) * Mult[tf >> 14]);
}

Übrigens, ich habe mich in meinen früheren Beiträgen geirrt. Aus irgendeinem Grund dachte ich, ein Monat hätte 28 Tage und nicht 30. Ich verstehe nicht, woher ich das habe.
Ich kann meine Beiträge, die älter als 1 Stunde sind, nicht mehr korrigieren.

Meine korrekte Version ist also diese:

int PeriodSecondsFast(ENUM_TIMEFRAMES tf) {
   return (tf>>14==0)?(tf&0xFF)*60:(tf>>14==1)?(tf&0xFF)*60*60:(tf>>14==2)?60*60*24*7:60*60*24*30;
}

Keiner braucht die Sekunden des Monats, da die Monate unterschiedlich lang sind.

 
Nikolai Semko # :

Übrigens, ich habe mich in meinen früheren Beiträgen geirrt. Aus irgendeinem Grund dachte ich, ein Monat hätte 28 Tage und nicht 30. Ich verstehe nicht, woher ich das habe.
Ich kann meine Beiträge, die älter als 1 Stunde sind, nicht mehr korrigieren.

Meine korrekte Version lautet also wie folgt:

Keiner braucht die Sekunden des Monats, da die Monate unterschiedlich lang sind.

Wie kommen Sie darauf, dass dies schneller ist als PeriodSeconds(x)?
 
Alain Verleyen #:
Wie kommen Sie darauf, dass dies schneller ist als PeriodSeconds(x)?

der Test aus diesem Beitrag

reicht es aus, die Leistung von getStartTimeOfBar() mit PeriodSeconds() und mit PeriodSecondsFast() zu vergleichen

Der Vergleich sollte auf jedem TF außer MN1 durchgeführt werden

Die Leistung ist etwa 2-mal höher. Vielleicht sogar um das Dreifache, wenn man bedenkt, dass wir die gesamte Iteration messen.


oder reicht es, diese beiden Werte zu vergleichen


2023.11.14 22:44:52.581 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H8========
2023.11.14 22:44:52.581 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000623961600, время выполнения 1 иттерации = 6.80 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 22:44:52.581 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000623961600, время выполнения 1 иттерации = 3.40 наносекунд - Быстрый расчет
2023.11.14 22:44:57.734 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000252960000, время выполнения 1 иттерации = 515301.20 наносекунд - Расчет через iBarShift
2023.11.14 22:44:57.734 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 22:45:16.253 timeToStartMonth (EURUSD,M1)    60 ,120 ,180 ,240 ,300 ,360 ,600 ,720 ,900 ,1200 ,1800 ,3600 ,7200 ,10800 ,14400 ,21600 ,28800 ,43200 ,86400 ,604800 ,2592000 ,
2023.11.14 22:45:16.253 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.14 22:45:16.253 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000769600080, время выполнения 1 иттерации = 3.70 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 22:45:16.253 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000769600080, время выполнения 1 иттерации = 1.90 наносекунд - Быстрый расчет
2023.11.14 22:45:16.471 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000394543440, время выполнения 1 иттерации = 21746.60 наносекунд - Расчет через iBarShift
2023.11.14 22:45:16.471 timeToStartMonth (EURUSD,M1)    ========================================================================
2023.11.14 22:45:57.038 timeToStartMonth (EURUSD,M1)    60 ,120 ,180 ,240 ,300 ,360 ,600 ,720 ,900 ,1200 ,1800 ,3600 ,7200 ,10800 ,14400 ,21600 ,28800 ,43200 ,86400 ,604800 ,2592000 ,
2023.11.14 22:45:57.038 timeToStartMonth (EURUSD,M1)    =====LOOP=10000========STEPS=100000 seconds======PERIOD_H1========
2023.11.14 22:45:57.038 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000751999200, время выполнения 1 иттерации = 5.30 наносекунд - Расчет через структуру MqlDateTime
2023.11.14 22:45:57.038 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000751999200, время выполнения 1 иттерации = 3.00 наносекунд - Быстрый расчет
2023.11.14 22:45:57.072 timeToStartMonth (EURUSD,M1)    контрольная сумма - 12000378405600, время выполнения 1 иттерации = 3410.10 наносекунд - Расчет через iBarShift
2023.11.14 22:45:57.072 timeToStartMonth (EURUSD,M1)    ========================================================================

 
Nikolai Semko # :

den Test aus diesem Beitrag

es genügt, die Arbeit von getStartTimeOfBar() mit PeriodSeconds() und mit PeriodSecondsFast() zu vergleichen

Der Vergleich sollte auf jedem TF außer MN1 durchgeführt werden

Die Leistung ist etwa 2-mal höher. Vielleicht sogar um das Dreifache, wenn man bedenkt, dass wir die gesamte Iteration messen.


oder reicht es, diese beiden Werte zu vergleichen



Vielleicht übersehe ich etwas, aber ich habe Ihr Skript verwendet, um (nur) PeriodSeconds zu überprüfen.


Dateien:
__.mq5  13 kb