Características da linguagem mql5, subtilezas e técnicas - página 236

 
Uma implementação mais rápida da função PeriodSeconds() padrão:
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 #:
Uma implementação mais rápida da função PeriodSeconds() padrão:

Dei uma olhada no 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

Provavelmente não é mais rápida. No entanto, já ouvi falar da maravilhosa velocidade do 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 #:

Dei uma olhada no formato.

Provavelmente não o acelerará. No entanto, ouvi falar da velocidade milagrosa da troca.

Parece mais longo, mas não notei nenhuma diferença no desempenho.

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

Portanto, acho que uma versão de uma linha ainda é preferível.

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

parece mais longo

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 agora vamos converter tudo isso em matrizes e ONX :-)

 
fxsaber #:

Sim, você poderia fazer isso. Mais legível.
O desempenho em meu laptop é o mesmo.

 

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 propósito, eu estava errado em minhas postagens anteriores. Por algum motivo, pensei que havia 28 dias em um mês, não 30. Não entendo de onde tirei essa conclusão.
Não consigo mais corrigir minhas postagens que têm mais de uma hora.

Portanto, minha versão correta é esta:

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

No entanto, ninguém precisa dos segundos do mês, pois os meses têm durações diferentes

 
Nikolai Semko # :

A propósito, eu estava errado em minhas postagens anteriores. Por algum motivo, pensei que havia 28 dias em um mês, não 30. Não entendo de onde tirei isso.
Não consigo corrigir minhas postagens com mais de 1 hora.

Portanto, minha versão correta é a seguinte:

No entanto, ninguém precisa dos segundos do mês, pois os meses têm durações diferentes

O que faz você pensar que isso é mais rápido do que PeriodSeconds(x)?
 
Alain Verleyen #:
O que faz você pensar que isso é mais rápido do que PeriodSeconds(x)?

O teste desta postagem

é suficiente para comparar o desempenho de getStartTimeOfBar() com PeriodSeconds() e com PeriodSecondsFast()

A comparação deve ser feita em qualquer TF, exceto MN1

O desempenho é cerca de duas vezes maior. Talvez 3 vezes, levando em conta que medimos a iteração inteira.


ou é suficiente comparar esses dois valores?


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

o teste desta postagem

basta comparar o trabalho de getStartTimeOfBar() com PeriodSeconds() e com PeriodSecondsFast()

A comparação deve ser feita em qualquer TF, exceto MN1

O desempenho é cerca de duas vezes maior. Talvez 3 vezes, levando em conta que medimos a iteração inteira.


ou é suficiente comparar esses dois valores?



Talvez esteja faltando alguma coisa, mas usei seu script para verificar o PeriodSeconds (apenas).


Arquivos anexados:
__.mq5  13 kb