Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 236

 
Un'implementazione più veloce della funzione standard 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 #:
Un'implementazione più veloce della funzione standard PeriodSeconds():

Ho guardato il formato.

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

Probabilmente non è più veloce. Ho sentito parlare, però, della meravigliosa velocità di switch.

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 #:

Ho guardato il formato.

Probabilmente non lo velocizzerà. Ho sentito parlare della miracolosa velocità dello switch.

Sembra più lungo, ma non ho notato alcuna differenza di prestazioni.

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;
}

Quindi penso che una versione a una riga sia ancora preferibile.

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 #:

sembra più lungo

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]);
}
 

e ora di convertire tutto questo in matrici e ONX :-)

 
fxsaber #:

Sì, si può fare così. Più leggibile. Le prestazioni di
sul mio portatile sono le stesse.

 

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]);
}

A proposito, mi sono sbagliato nei miei post precedenti. Per qualche motivo pensavo che in un mese ci fossero 28 giorni, non 30. Non capisco come mi sia venuto in mente.
Non riesco più a correggere i miei messaggi che hanno più di un'ora.

Quindi la mia versione corretta è questa:

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;
}

Nessuno ha bisogno dei secondi del mese, però, dato che i mesi sono di lunghezza diversa.

 
Nikolai Semko # :

A proposito, mi sono sbagliato nei miei post precedenti. Per qualche ragione pensavo che in un mese ci fossero 28 giorni e non 30. Non capisco dove ho sbagliato.
Non riesco a correggere i miei messaggi che sono più vecchi di un'ora.

Quindi la mia versione corretta è la seguente:

Nessuno ha bisogno dei secondi del mese, però, dato che i mesi sono di lunghezza diversa.

Cosa ti fa pensare che questo sia più veloce di PeriodSeconds(x)?
 
Alain Verleyen #:
Cosa vi fa pensare che sia più veloce di PeriodSeconds(x)?

il test di questo post

è sufficiente per confrontare le prestazioni di getStartTimeOfBar() con PeriodSeconds() e con PeriodSecondsFast()

Il confronto deve essere effettuato su qualsiasi TF tranne MN1

Le prestazioni sono superiori di circa 2 volte. Forse di 3 volte, considerando che misuriamo l'intera iterazione.


o è sufficiente confrontare questi due valori


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 # :

il test di questo post

è sufficiente confrontare il lavoro di getStartTimeOfBar() con PeriodSeconds() e con PeriodSecondsFast()

Il confronto deve essere fatto su qualsiasi TF tranne MN1

Le prestazioni sono superiori di circa 2 volte. Forse di 3 volte, considerando che misuriamo l'intera iterazione.


o è sufficiente confrontare questi due valori



Forse mi sfugge qualcosa, ma ho usato il tuo script per controllare PeriodSeconds (solo).


File:
__.mq5  13 kb