Discusión sobre el artículo "LifeHack para tráders: cocinamos ForEach usando #define" - página 2

 
Rashid Umarov:

Una técnica interesante y no obvia )

Es defectuosa (para las estructuras vagas) y no es óptima.

 
fxsaber:
Para el copiador

no es muy conveniente. no es obvio que haya que declarar una variable externa.

[Eliminado]  

"En las plantillas" significaba esto:

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;

Si quieres ser confuso, todavía puedes hacer esto:

#define  CVolume SeriesVolume< long >

CVolume Volume;

Todo lo demás es innecesario.

 
fxsaber:

A veces es útil escribir menos

Es sólo una cuestión de viabilidad, usabilidad y rendimiento.

El rendimiento del programa no se resentirá. Pero ocultar excesivos detalles a tus ojos es un efecto positivo. Deberías recordar y utilizar este truco defyne.

[Eliminado]  
¿Está listo el código en la biblioteca estándar?
 
fxsaber:

¡Terriblemente caro! Si realmente quieres hacerlo a través de la estructura, por lo menos deberías haberlo hecho. Y no hay ningún cheque por alguna razón.

SymbolInfoDouble es totalmente compatible con MT4.

Medición del rendimiento

#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

¡Estaba totalmente equivocado! SymbolInfoDouble es dos veces más lento que SymbolInfoTick.

 
fxsaber:

Medición del rendimiento


Resultado


Estaba totalmente equivocado. SymbolInfoDouble es el doble de lento que SymbolInfoTick.

Gracias por la medición del rendimiento.

Resulta que la documentación de SymbolInfoDouble no miente:

Nota

Si la función se utiliza para obtener información sobre el último tick, es mejor utilizarSymbolInfoTick().

 
fxsaber:

Medición del rendimiento

Resultado

Estaba totalmente equivocado. SymbolInfoDouble es el doble de lento que SymbolInfoTick.

¿El uso de static afecta a la velocidad? Pido disculpas por no haberlo comprobado yo mismo, pero creo que ya se ha comparado.

 
Rashid Umarov:

¿El uso de estática afecta a la velocidad? Pido disculpas por no haberlo comprobado yo mismo, pero creo que ya lo has comparado.

En este caso no afecta. Creo que es un error del compilador.

 
fxsaber:

Estaba completamente equivocado. SymbolInfoDouble es el doble de lento que SymbolInfoTick.

Incompetente. Resultado en 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

Donde se necesita rendimiento (Optimizador), es mejor usar SymbolInfoDouble. En el mundo real - no hay diferencia.


ZY Usted debe medir la velocidad de las funciones en un entorno donde el rendimiento es importante - Tester.