Discussion of article "LifeHack for traders: Blending ForEach with defines (#define)" - page 2

 
Rashid Umarov:

An interesting and non-obvious technique )

It's flawed (for bummer structures) and not optimal.

 
fxsaber:
To the copybook

it is not very convenient. it is not obvious that an external variable must be declared.

 

"On templates" meant this:

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;

If you want to be confusing, you can still do this:

#define  CVolume SeriesVolume< long >

CVolume Volume;

Everything else is just unnecessary.

 
fxsaber:

Less writing is sometimes handy

It's just a question of feasibility, usability and performance.

The performance of the programme will not suffer. But hiding excessive details from your eyes is a positive effect. You should remember and use this defyne trick.

[Deleted]  
Is the code ready in the standard library?
 
fxsaber:

Terribly expensive! If you really want to do it through the structure, you should have at least done it. And there is no check for some reason.

SymbolInfoDouble is fully compliant with MT4.

Performance measurement

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


Result

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

I was absolutely wrong! SymbolInfoDouble is twice as slow as SymbolInfoTick.

 
fxsaber:

Performance measurement


Result


I was absolutely wrong! SymbolInfoDouble is twice as slow as SymbolInfoTick.

Thanks for the performance measurement.

It turns out that SymbolInfoDouble documentation is not lying:

Note

If the function is used to get information about the last tick, it is better to useSymbolInfoTick().

 
fxsaber:

Performance measurement

Result

I was absolutely wrong! SymbolInfoDouble is twice as slow as SymbolInfoTick.

Does using static affect the speed? I apologise for not checking it myself, but I think you have already compared.

 
Rashid Umarov:

Does using static affect the speed? I apologise for not checking it myself, but I think you have already compared it.

In this case it doesn't. I think it is a bug of the compiler.

 
fxsaber:

I was completely wrong! SymbolInfoDouble is twice as slow as SymbolInfoTick.

Incompetent. Result in 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

Where you need performance (Optimiser), it is better to use SymbolInfoDouble. In the real world - no difference.


ZY You should measure the speed of functions in an environment where performance is important - Tester.