151 lines
8 KiB
MQL5
151 lines
8 KiB
MQL5
#ifndef LIB_DBG_PERFCOUNTER_FUNCTIONS_MQH_INCLUDED
|
|
#define LIB_DBG_PERFCOUNTER_FUNCTIONS_MQH_INCLUDED
|
|
#property version "5.10"
|
|
/**********************************************************************************
|
|
* Copyright (C) 2020 Dominik Egert <info@freie-netze.de>
|
|
*
|
|
* This file is the performance cuonter library include file.
|
|
*
|
|
* Lisence applied: GPLv2
|
|
* https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*
|
|
* Author Dominik Egert / Freie Netze UG.
|
|
**********************************************************************************
|
|
*
|
|
* Version: 5.10
|
|
* State: public
|
|
*
|
|
* File information
|
|
* ================
|
|
*
|
|
*
|
|
*
|
|
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************************************************************************************/
|
|
//
|
|
// BEGIN Performance profiling support
|
|
|
|
|
|
#ifdef LIB_PERF_PROFILING
|
|
|
|
// Internal global counters
|
|
#ifdef __MQL5__
|
|
namespace lib_perf
|
|
{
|
|
|
|
#endif
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, perf_counters) = 0x00;
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, perf_array)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, perf_min)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, perf_max)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, _call_counter)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, _perf_array)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, _perf_min)[];
|
|
static ulong LIB_DBG_NAMESPACE_DEF(lib_perf, _perf_max)[];
|
|
|
|
void LIB_DBG_NAMESPACE_DEF(lib_perf, perf_print_details)(const ulong exec_micros, const ulong avg_micros, const ulong min_micros, const ulong max_micros, const ulong call_count, string prefix)
|
|
{
|
|
StringReplace(prefix, "\n", "");
|
|
printf("%s %s", prefix, PERF_PROFILING_OUTPUT_RESULTS(exec_micros, call_count, avg_micros, min_micros, max_micros));
|
|
};
|
|
|
|
#ifdef __MQL5__
|
|
const string LIB_DBG_NAMESPACE_DEF(lib_perf, perf_string_concatenate)(string p1, string p2, string p3, string p4)
|
|
{
|
|
string out = NULL;
|
|
StringConcatenate(out, p1, p2, p3, p4);
|
|
return(out);
|
|
}
|
|
|
|
#else
|
|
const string LIB_DBG_NAMESPACE_DEF(lib_perf, perf_string_concatenate)(string p1, string p2, string p3, string p4)
|
|
{ return(StringConcatenate(p1, p2, p3, p4)); }
|
|
|
|
#endif
|
|
|
|
const int LIB_DBG_NAMESPACE_DEF(lib_perf, md5_hash_id)(const string p_in)
|
|
{
|
|
static long p_ids[];
|
|
uchar inp_data[];
|
|
uchar _key[];
|
|
uchar out_data[];
|
|
StringToCharArray(p_in, inp_data);
|
|
if(CryptEncode(CRYPT_HASH_MD5, inp_data, _key, out_data) == 0)
|
|
{
|
|
printf("Internal error in LIB_PERF: err_no: %i", _LastError);
|
|
return(-1);
|
|
}
|
|
|
|
const long l_id = (out_data[7] << 56) | (out_data[6] << 48) | (out_data[5] << 40) | (out_data[4] << 32) | (out_data[3] << 24) | (out_data[2] << 16) | (out_data[1] << 8) | (out_data[0]);
|
|
int cnt = ArraySize(p_ids) - 1;
|
|
for(; (cnt >= 0) && (p_ids[cnt] != l_id) && !_StopFlag; cnt--);
|
|
|
|
if(cnt == -1)
|
|
{
|
|
cnt = ArrayResize(p_ids, ArraySize(p_ids) + 1, 512) - 1;
|
|
p_ids[cnt] = l_id;
|
|
}
|
|
return(cnt);
|
|
};
|
|
|
|
void LIB_DBG_NAMESPACE_DEF(lib_perf, update_counters)(const ulong start, const ulong end, const int _perf_id, const string func_id, const string file, const string function, const int line)
|
|
{
|
|
const int perf_id = (_perf_id == -1) ? LIB_DBG_NAMESPACE(lib_perf, md5_hash_id)(LIB_DBG_NAMESPACE(lib_perf, perf_string_concatenate)(func_id, file, function, IntegerToString(line))) : _perf_id;
|
|
if(ArraySize(LIB_DBG_NAMESPACE(lib_perf, _call_counter)) <= (int)perf_id)
|
|
{
|
|
const int prev_size = ArraySize(LIB_DBG_NAMESPACE(lib_perf, _call_counter));
|
|
ArrayResize(LIB_DBG_NAMESPACE(lib_perf, _call_counter), perf_id + 1, 512);
|
|
ArrayResize(LIB_DBG_NAMESPACE(lib_perf, _perf_array), perf_id + 1, 512);
|
|
ArrayResize(LIB_DBG_NAMESPACE(lib_perf, _perf_min), perf_id + 1, 512);
|
|
ArrayResize(LIB_DBG_NAMESPACE(lib_perf, _perf_max), perf_id + 1, 512);
|
|
ArrayFill(LIB_DBG_NAMESPACE(lib_perf, _call_counter), prev_size, perf_id + 1 - prev_size, 0);
|
|
ArrayFill(LIB_DBG_NAMESPACE(lib_perf, _perf_array), prev_size, perf_id + 1 - prev_size, 0);
|
|
ArrayFill(LIB_DBG_NAMESPACE(lib_perf, _perf_min), prev_size, perf_id + 1 - prev_size, ULONG_MAX);
|
|
ArrayFill(LIB_DBG_NAMESPACE(lib_perf, _perf_max), prev_size, perf_id + 1 - prev_size, 0);
|
|
}
|
|
|
|
// Update data
|
|
const ulong exec_micros = (start > end) ? (start - end) : (end - start);
|
|
LIB_DBG_NAMESPACE(lib_perf, _call_counter)[perf_id]++;
|
|
LIB_DBG_NAMESPACE(lib_perf, _perf_array)[perf_id] += exec_micros;
|
|
LIB_DBG_NAMESPACE(lib_perf, _perf_min)[perf_id] = (LIB_DBG_NAMESPACE(lib_perf, _perf_min)[perf_id] > exec_micros) ? exec_micros : LIB_DBG_NAMESPACE(lib_perf, _perf_min)[perf_id];
|
|
LIB_DBG_NAMESPACE(lib_perf, _perf_max)[perf_id] = (LIB_DBG_NAMESPACE(lib_perf, _perf_max)[perf_id] < exec_micros) ? exec_micros : LIB_DBG_NAMESPACE(lib_perf, _perf_max)[perf_id];
|
|
|
|
// Print user info
|
|
LIB_DBG_NAMESPACE(lib_perf, perf_print_details)(exec_micros, LIB_DBG_NAMESPACE(lib_perf, _perf_array)[perf_id] / LIB_DBG_NAMESPACE(lib_perf, _call_counter)[perf_id], LIB_DBG_NAMESPACE(lib_perf, _perf_min)[perf_id], LIB_DBG_NAMESPACE(lib_perf, _perf_max)[perf_id], LIB_DBG_NAMESPACE(lib_perf, _call_counter)[perf_id], PERF_PROFILING_OUTPUT_PREFIX(file, function, line, func_id));
|
|
}
|
|
|
|
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, const string file, const string function, const int line)
|
|
{ LIB_DBG_NAMESPACE(lib_perf, update_counters)(start, end, perf_id, func_id, file, function, line); return(retval); };
|
|
|
|
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, const string file, const string function, const int line)
|
|
{ LIB_DBG_NAMESPACE(lib_perf, update_counters)(start, end, perf_id, func_id, file, function, line); return(retval); };
|
|
|
|
template <typename T>
|
|
T LIB_DBG_NAMESPACE_DEF(lib_perf, perf_O_call)(const ulong start, T& retval, const ulong end, const int perf_id, const string func_id, const string file, const string function, const int line)
|
|
{ LIB_DBG_NAMESPACE(lib_perf, update_counters)(start, end, perf_id, func_id, file, function, line); return(retval); };
|
|
|
|
template <typename T>
|
|
T* LIB_DBG_NAMESPACE_DEF(lib_perf, perf_O_call)(const ulong start, T* retval, const ulong end, const int perf_id, const string func_id, const string file, const string function, const int line)
|
|
{ LIB_DBG_NAMESPACE(lib_perf, update_counters)(start, end, perf_id, func_id, file, function, line); return(retval); };
|
|
|
|
#ifdef __MQL5__
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
//
|
|
// END Debugging support
|
|
//*********************************************************************************************************************************************************/
|
|
#endif // LIB_DBG_PERFCOUNTER_FUNCTIONS_MQH_INCLUDED
|