Discussão do artigo "LifeHack para traders: "amassando" ForEach com os define (#define)" - página 2

 
Rashid Umarov:

Uma técnica interessante e não óbvia)

Ela é falha (para estruturas de chatice) e não é ideal.

 
fxsaber:
Para o copybook

não é muito conveniente. Não é óbvio que uma variável externa deva ser declarada.

[Excluído]  

"Em modelos" significava isso:

template< typename T >
class SeriesVolume
{
public:
   T operator[]( const int i ) const
   {
      long val[1];
      if( CopyTickVolume( Symbol(), Period(), i, 1, val ) == 1 ){
         return (T)val[0];
      }
      return -1;
   }
};

SeriesVolume< long > Volume;

Se você quiser ser confuso, ainda pode fazer isso:

#define  CVolume SeriesVolume< long >

CVolume Volume;

Todo o resto é desnecessário.

 
fxsaber:

Às vezes, é útil escrever menos

É apenas uma questão de viabilidade, usabilidade e desempenho.

O desempenho do programa não será prejudicado. Mas ocultar detalhes excessivos de seus olhos é um efeito positivo. Você deve se lembrar e usar esse truque desafiador.

[Excluído]  
O código está pronto na biblioteca padrão?
 
fxsaber:

Terrivelmente caro! Se você realmente quiser fazer isso por meio da estrutura, deveria pelo menos ter feito isso. E, por algum motivo, não há verificação.

O SymbolInfoDouble é totalmente compatível com o MT4.

Medição de desempenho

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

double GetAsk()
{
  static MqlTick tick = {0};
  
  return(SymbolInfoTick(Symbol(),tick) ? tick.ask : 0);
}

#define  AMOUNT 1 e6

void OnStart()
{
  double Sum = 0;
  
  BENCH(for (int i = 0; i < AMOUNT; i++) Sum += GetAsk())
  BENCH(for (int i = 0; i < AMOUNT; i++) Sum += SymbolInfoDouble(_Symbol, SYMBOL_ASK))
  
  Print(Sum);
}


Resultado

Time[for(inti=0;i<AMOUNT;i++)Sum+=GetAsk()] = 78952
Time[for(inti=0;i<AMOUNT;i++)Sum+=SymbolInfoDouble(_Symbol,SYMBOL_ASK)] = 162606

Eu estava absolutamente errado! O SymbolInfoDouble é duas vezes mais lento que o SymbolInfoTick.

 
fxsaber:

Medição de desempenho


Resultados


Eu estava absolutamente errado! O SymbolInfoDouble é duas vezes mais lento que o SymbolInfoTick.

Obrigado pela medição de desempenho.

Parece que a documentação do SymbolInfoDouble não está mentindo:

Observação

Se a função for usada para obter informações sobre o último tick, é melhor usarSymbolInfoTick().

 
fxsaber:

Medição de desempenho

Resultados

Eu estava absolutamente errado! O SymbolInfoDouble é duas vezes mais lento que o SymbolInfoTick.

O uso de estática afeta a velocidade? Peço desculpas por não ter verificado isso pessoalmente, mas acho que você já fez a comparação.

 
Rashid Umarov:

O uso de estática afeta a velocidade? Peço desculpas por não ter verificado isso pessoalmente, mas acho que você já fez a comparação.

Nesse caso, não afeta. Acho que é um bug do compilador.

 
fxsaber:

Eu estava completamente errado! O SymbolInfoDouble é duas vezes mais lento que o SymbolInfoTick.

Incompetente. Resultado no Tester

2017.09.01 00:00:10   Time[for(inti=0;i<AMOUNT;i++)Sum+=GetAsk()] = 87424
2017.09.01 00:00:10   Time[for(inti=0;i<AMOUNT;i++)Sum+=SymbolInfoDouble(_Symbol,SYMBOL_ASK)] = 83410

Quando você precisa de desempenho (otimizador), é melhor usar o SymbolInfoDouble. No mundo real, não há diferença.


ZY Você deve medir a velocidade das funções em um ambiente em que o desempenho é importante - Tester.