Libraries: MQL Plus Enhanced Debugging Support

 

MQL Plus Enhanced Debugging Support:

An (optional) include file to enhance debugging experience.

MQL Plus Enhanced Debugging Support

Author: Dominik Egert

 

Updated version available.

Please see description of code base for further details, also see documentation in header file lib_debug.mqh.

 

Form now on this code is part of the main Project "MQLplus" and shared via the Shared Cloud Storage.

You can find it under "MQLplus" "MQLplus Include Library Collection" and download it there.

You will find the most current version in there and are welcomed to contribute if you wish.

 
Dominik Christian Egert #:
You could try the macros for performance measurements in this project.

Unfortunately, I could not understand your library. Please show an example of measurement in the code below.

int f1() { Sleep(100); return(1); }
int f2() { Sleep(200); return(2); }
int f3() { Sleep(300); return(3); }

int g()
{
  return((f1() + f2() + f3() == 6) ?
                       f1() * f2() : 0);
}

void OnStart()
{
  if (g() == 2)   
    Print(f3() == 3);

  Print(f1());
  Print(f2());
}

It is necessary to measure the execution time of the pieces of code highlighted in yellow.

 
fxsaber #:

Unfortunately, I could not understand your library. Please show an example of measurement in the code below.

It is necessary to measure the execution time of the pieces of code highlighted in yellow.

I am sorry for the confusion, in fact, I had to fix some bugs before this works like it should. 

I published the most current version on CodeBase for you to download.

Anyways, thank you for your patience...


Here is how to apply the library to your code. - Should be pretty straight forward. - Depending on what you want to measure, you probably would want to adjust the measurement-blocks. 

#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh>


int f1() { PERF_COUNTER_BEGIN; Sleep(100); PERF_COUNTER_END; return(1); }
int f2() { PERF_COUNTER_BEGIN; Sleep(200); PERF_COUNTER_END; return(2); }
int f3() { PERF_COUNTER_BEGIN; Sleep(300); PERF_COUNTER_END; return(3); }

int g()
{
  return((f1() + f2() + f3() == 6) ?
                       f1() * f2() : 0);
}

//+------------------------------------------------------------------+
//| Service program start function                                   |
//+------------------------------------------------------------------+
void OnStart()
{
    // Create additional performance counters
    //  IDs can be specified freely
    PERF_COUNTER_DEFINE_ID(if_g_func);
    PERF_COUNTER_DEFINE_ID(call_f3_func);
    PERF_COUNTER_DEFINE_ID(printf_f1);
    PERF_COUNTER_DEFINE_ID(printf_f2);

    // How long will the execution of this block take
    PERF_COUNTER_BEGIN;

        PERF_COUNTER_SET_ID(if_g_func);
        if (g() == 2)   
        { 
            PERF_COUNTER_CLOSE_ID(if_g_func);
        
            PERF_COUNTER_SET_ID(call_f3_func);
            Print(f3() == 3); 
            PERF_COUNTER_CLOSE_ID(call_f3_func);
        }
        else
        { PERF_COUNTER_CLOSE_ID(if_g_func); }


        PERF_COUNTER_SET_ID(printf_f1);
        Print(f1());
        PERF_COUNTER_CLOSE_ID(printf_f1);

        PERF_COUNTER_SET_ID(printf_f2);
        Print(f2());
        PERF_COUNTER_CLOSE_ID(printf_f2);
    
    // Close and print results of this execution block
    PERF_COUNTER_END;
    return;

};


For your information:

The macros are designed in such way, the last statement on opening a measurement block will be saving the microsecond timestamp. And the first statement on closing will be the saving of the microsecond timestamp.

This would be the output of your code, on my machine:


2023.04.26 10:28:31.647 Playground      f1() Runtime: 110832 microseconds; average(110832), min(110832), max(110832); total calls: 1
2023.04.26 10:28:31.850 Playground      f2() Runtime: 203122 microseconds; average(203122), min(203122), max(203122); total calls: 1
2023.04.26 10:28:32.162 Playground      f3() Runtime: 312379 microseconds; average(312379), min(312379), max(312379); total calls: 1
2023.04.26 10:28:32.272 Playground      f1() Runtime: 109387 microseconds; average(110109), min(109387), max(110832); total calls: 2
2023.04.26 10:28:32.463 Playground      f2() Runtime: 191643 microseconds; average(197382), min(191643), max(203122); total calls: 2
2023.04.26 10:28:32.463 Playground      if_g_func: Runtime: 927508 microseconds; average(927508), min(927508), max(927508); total calls: 1
2023.04.26 10:28:32.776 Playground      f3() Runtime: 312501 microseconds; average(312440), min(312379), max(312501); total calls: 2
2023.04.26 10:28:32.776 Playground      true
2023.04.26 10:28:32.776 Playground      call_f3_func: Runtime: 312543 microseconds; average(312543), min(312543), max(312543); total calls: 1
2023.04.26 10:28:32.885 Playground      f1() Runtime: 109430 microseconds; average(109883), min(109387), max(110832); total calls: 3
2023.04.26 10:28:32.885 Playground      1
2023.04.26 10:28:32.885 Playground      printf_f1: Runtime: 109457 microseconds; average(109457), min(109457), max(109457); total calls: 1
2023.04.26 10:28:33.088 Playground      f2() Runtime: 203076 microseconds; average(199280), min(191643), max(203122); total calls: 3
2023.04.26 10:28:33.088 Playground      2
2023.04.26 10:28:33.088 Playground      printf_f2: Runtime: 203101 microseconds; average(203101), min(203101), max(203101); total calls: 1
2023.04.26 10:28:33.088 Playground      OnStart() Runtime: 1552627 microseconds; average(1552627), min(1552627), max(1552627); total calls: 1
 
Dominik Christian Egert #:

Here is how to apply the library to your code.

Thanks for the example. You can see that not everything was measured. And big code changes are required.

It is very laborious and inconvenient, unfortunately.

 
fxsaber #:

Thanks for the example. You can see that not everything was measured. And big code changes are required.

It is very laborious and inconvenient, unfortunately.

What measurements are you missing?

How would you like it to be? - Could you show some (pseudo) example code, so I might be able to adapt the library to these needs, please.

I have added (maybe) to many measurements to show how it works. - I guess it could be stripped down quite a bit as far as I can see right now.


#define LIB_PERF_PROFILING
#include <MQLplus/lib_debug.mqh>



#define PERF_COUNTER_FUNC(x) PERF_COUNTER_BEGIN; x; PERF_COUNTER_END;
#define PERF_COUNTER_FUNC_ID(id, x) PERF_COUNTER_SET_ID(id); x; PERF_COUNTER_CLOSE_ID(id);



int f1() { PERF_COUNTER_FUNC(Sleep(100)); return(1); }
int f2() { PERF_COUNTER_FUNC(Sleep(200)); return(2); }
int f3() { PERF_COUNTER_FUNC(Sleep(300)); return(3); }


int g()
{
  return((f1() + f2() + f3() == 6) ?
                       f1() * f2() : 0);
}

//+------------------------------------------------------------------+
//| Service program start function                                   |
//+------------------------------------------------------------------+
void OnStart()
{
    // How long will the execution of this block take
    PERF_COUNTER_BEGIN;


    // Create additional performance counters
    //  IDs can be specified freely
    PERF_COUNTER_DEFINE_ID(if_g_func);
    PERF_COUNTER_DEFINE_ID(call_f3_func);
    PERF_COUNTER_DEFINE_ID(printf_f1);
    PERF_COUNTER_DEFINE_ID(printf_f2);


        PERF_COUNTER_SET_ID(if_g_func);
        if (g() == 2)   
        { 
            PERF_COUNTER_CLOSE_ID(if_g_func);
                        PERF_COUNTER_FUNC_ID(call_f3_func, Print(f3() == 3)); 
        }
        else
        { PERF_COUNTER_CLOSE_ID(if_g_func); }


        PERF_COUNTER_FUNC_ID(printf_f1, Print(f1()));
        PERF_COUNTER_FUNC_ID(printf_f2, Print(f2()));

    
    // Close and print results of this execution block
    PERF_COUNTER_END;
    return;

};

 
Dominik Christian Egert #:

What measurements are you missing?

Forum on trading, automated trading systems and testing trading strategies

Libraries: MQL Plus Enhanced Debugging Support

fxsaber, 2023.04.25 20:39

Unfortunately, I could not understand your library. Please show an example of measurement in the code below.

int g()
{
  return((f1() + f2() + f3() == 6) ?
                       f1() * f2() : 0);
}

How would you like it to be? - Could you show some (pseudo) example code, so I might be able to adapt the library to these needs, please.

I have added (maybe) to many measurements to show how it works. - I guess it could be stripped down quite a bit as far as I can see right now.

int f1() { Sleep(100); return(1); }
int f2() { Sleep(200); return(2); }
int f3() { Sleep(300); return(3); }

int g()
{
  return(TimeIt(f1() + f2() + f3() == 6) ?
                       TimeIt(f1() * f2()) : 0);
}

void OnStart()
{
  if (TimeIt(g()) == 2)   
    Print(TimeIt(f3() == 3));

  TimeIt(
  Print(f1());
  Print(f2());)
}
 
fxsaber #:

I know how to do it. Wait for the next update please.

But it will require two types of "TimeIt()"

One with a return value, maybe call it TimeItR() and one without a return value, call it TimeItV().

If that's a doable compromise for you, then I'll get you covered.

Thank you for the valuable input from a users perspective.



 
Dominik Christian Egert #:
I know how to do it. Wait for the next update please.

But it will require two types of "TimeIt()"

One with a return value, maybe call it TimeItR() and one without a return value, call it TimeItV().

If that's a doable compromise for you, then I'll get you covered.

Two types is a good option.

 
fxsaber #:

Two types is a good option.

Done. -Tested and published....


Please download current version and check to see if thats satisfying your requirements.