#ifndef LIB_DBG_PERFCOUNTER_FUNCTIONS_MQH_INCLUDED #define LIB_DBG_PERFCOUNTER_FUNCTIONS_MQH_INCLUDED #property version "5.10" /********************************************************************************** * Copyright (C) 2020 Dominik Egert * * 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 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 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 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 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