Libraries: MQL Plus Enhanced Debugging Support - page 3

 
After these changes.
            template <typename T>
//            T* LIB_DBG_NAMESPACE_DEF(lib_perf, perf_R_call)(const ulong start, T* retval, const ulong end, const int perf_id, const string func_id)
            T LIB_DBG_NAMESPACE_DEF(lib_perf, perf_R_call)(const ulong start, T &retval, const ulong end, const int perf_id, const string func_id)


It compiles.

#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh> // https://www.mql5.com/en/code/32071

#define TimeIt PERF_COUNTER_TIMEIT_R
#define TimeItV PERF_COUNTER_TIMEIT_V

class A
{
public:
  A() {};
  A( const A& ) { Sleep(500); }
};

template <typename T>
T GetT() { T Tmp; return(Tmp); }

void OnStart()
{
  TimeIt(GetT<int>());
  TimeIt(GetT<MqlTick>());
  TimeIt(GetT<A>());
  TimeIt(new A);
  TimeIt(GetT<A*>());
}


Result.

GetT<int>(): Runtime: 0 microseconds; 
GetT<MqlTick>(): Runtime: 0 microseconds; 
GetT<A>(): Runtime: 525391 microseconds; 
newA: Runtime: 30 microseconds; 
GetT<A*>(): Runtime: 0 microseconds; 
 
fxsaber #:

When do you need a macro for objects?


Since a while it is possible to return objects from functions, so if you would want to measure a function returning an object, you would need to use this macro instead.

This is due to a limitation of the compiler, not being able to distinguish between r-values, l-values and objects.

So if you would write a function accepting an object, it needs to be passed as reference, but you cannot pass (from your example) the addition of two results from functions (f1() + f2()), as they are not implicitly converted by the MQL compiler into a temporary/hidden variable, therefore the function receiving this may not use a reference (int &var) as input.

C/C++ allows this in contrast, and creates a temporary l-value to be used as input to the function.

In  fact, this is the last hurdle the MQL compiler has to it's way on supporting fully unified code generation.

Of course with one exception, enums.... These cannot be distinguished from objects in any meaningful way. At least I failed to do so up to now.

That's why three macros are required. Void is obvious. A function with no return value cannot be assigned to any variable. Return is used for explicit variable declaration. And Object is used to deal with references.

I'd be glad if anyone knew a way around this without altering the compiler.

But maybe, one day, Metaquotes will implement implicit r-value to l-value conversion for function call parameters.
 
fxsaber #:
After these changes.


It compiles.


Result.

oh well...

Exactly for this you would need to use the object macro...

This compiles without altering the library:

#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh> // https://www.mql5.com/en/code/32071

#define TimeIt PERF_COUNTER_TIMEIT_R
#define TimeItO PERF_COUNTER_TIMEIT_O
#define TimeItV PERF_COUNTER_TIMEIT_V

class A
{
public:
  A() {};
  A( const A& ) { Sleep(500); }
};

template <typename T>
T GetT() { T Tmp; return(Tmp); }

void OnInit()
{
  TimeIt(GetT<int>());
  TimeItO(GetT<MqlTick>());
  TimeItO(GetT<A>());
  TimeItO(new A);
  TimeItO(GetT<A*>());
}


By altering that part, you will create unnessary copies of the object. - Please use the O-Version of the macro for objects of type struct, class or interface....

BTW, this also compiles fine without editing the library...

void OnInit()
{
  TimeIt(GetT<int>());
  TimeItO(GetT<MqlTick>());
  TimeItO(GetT<A>());
  TimeItO(new A);
  TimeIt(GetT<A*>());
}
 
#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh> // https://www.mql5.com/en/code/32071

#define TimeIt PERF_COUNTER_TIMEIT_R
#define TimeItV PERF_COUNTER_TIMEIT_V

void OnStart()
{
  MqlTick Ticks[];
  
  if (TimeIt(CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 1)) > 0)
    TimeItV(ArrayPrint(Ticks)); // '_perf_id_20' - undeclared identifier
}
 
fxsaber #:

Got it...

I never use if() without brackets....

Change this line (Line Number 3351 in lib_debug.mqh

    #define PERF_COUNTER_TIMEIT_V(x)                    PERF_COUNTER_DEFINE_ID(__LINE__); PERF_COUNTER_BEGIN_ID(__LINE__); x; PERF_COUNTER_CLOSE_CUSTOM(StringFormat("%s() @Line ", __FUNCTION__), __LINE__);

to this line:

    #define PERF_COUNTER_TIMEIT_V(x)                    { PERF_COUNTER_DEFINE_ID(__LINE__); PERF_COUNTER_BEGIN_ID(__LINE__); x; PERF_COUNTER_CLOSE_CUSTOM(StringFormat("%s() @Line ", __FUNCTION__), __LINE__); }

that will fix the error...


I will post the update on shared storage now... and update the CodeBase

 
Fernando Carreiro #:

Yes, MQLplus is a shared public project!


Thanks, I need to rest
 
Dominik Christian Egert #:

By altering that part, you will create unnessary copies of the object. - Please use the O-Version of the macro for objects of type struct, class or interface....

#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh> // https://www.mql5.com/en/code/32071

#define TimeIt PERF_COUNTER_TIMEIT_R
#define TimeItV PERF_COUNTER_TIMEIT_V
#define TimeItO PERF_COUNTER_TIMEIT_O

class A
{
public:
  A() { Print(__FUNCSIG__); };
  A( const A& ) { Print(__FUNCSIG__); }
};

template <typename T>
T GetT() { T Tmp; return(Tmp); }

void OnStart()
{
  Print("\nTimeItO");
  TimeItO(GetT<A>());

  Print("\nTimeIt (changed)");
  TimeIt(GetT<A>());
}


TimeItO
A::A()
A::A(const A&)
GetT<A>(): Runtime: 44 microseconds; 
A::A(const A&)

TimeIt
A::A()
A::A(const A&)
GetT<A>(): Runtime: 6 microseconds; 
A::A(const A&)
 

Thank you all for the steady contributions, its not as easy to have an overview of all use cases, and by such complex integration, its easy to miss some edges....


Hope everything is beginning to work as expected slowly.... :-)

 
TimeIt(Func()); From __LINE__, __FILE__, __FUNCTION__ ?
...
TimeIt(Func()); From __LINE__, __FILE__, __FUNCTION__ ?
 
fxsaber #:


I have taken a look at this phenomenon, and I am sorry to disappoint you, but there is no way this can be influenced by us.


The MQL compiler has a few very strange behaviours concerning performance, and I have had the most ridicolous findings within source code. - I reported all of these things to Alexey from Metaquotes, and I never received a satisactory answer.

It might be, by adding some comment to the lib_debug.mqh, this effect could change and move to another function. - Yes, I know, htat sounds completley like abracadabra, but thats what it is. - If you would like to investigate on that issue more, I am very willing to share the proof with you, which I have also given to metaquotes to investigate....


You will find lots of inconsistencies when regarding performance measurements. - As said, and I am sure you can see as well ,the cod eis exactly the same for both functions, still one takes significant longer than the other. - Thats due to whatever the compiler does.

If you want, Ill share the project with you, you will get an even more detailed version of that problem. - Unsolved.