MQLplus/lib_debug/lib_perf_counter_macros.mqh

85 lines
6.5 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:52 +02:00
#ifndef LIB_DBG_PERFCOUNTER_MACROS_MQH_INCLUDED
#define LIB_DBG_PERFCOUNTER_MACROS_MQH_INCLUDED
#property version "5.10"
/**********************************************************************************
* Copyright (C) 2020 Dominik Egert <info@freie-netze.de>
*
* This file is the performance cuonter main user macros 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
// Output formatting macro
#define PERF_PROFILING_OUTPUT_PREFIX(_fl, _fnc, _ln, _fid) StringFormat(">>>perf_profiling<<< >%s< %s(){ @%i:%-25s=> ", _fl, _fnc, _ln, ((_fid == "") || (_fid == NULL) ? " " : " [" + _fid + "] "))
#define PERF_PROFILING_OUTPUT_RESULTS(ex_tm, cnt, avg, min, max) StringFormat("Runtime: %llu micros; %s }", ex_tm, (cnt < 2) ? "" : PERF_PROFILING_OUTPUT_DETAILS(avg, min, max, cnt))
#define PERF_PROFILING_OUTPUT_DETAILS(avg, min, max, cnt) StringFormat("average(%llu), min(%llu), max(%llu); total calls: %i", avg, min, max, cnt)
// Output helper macros
#define PERF_COUNTER_GET_AVERAGE(x) (LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] / _perf_calls_##x)
#define PERF_COUNTER_GET_MIN(x) LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x]
#define PERF_COUNTER_GET_MAX(x) LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x]
// Performance output format string
#define PERF_OUTPUT_FORMAT_ID(id, x) LIB_DBG_NAMESPACE(lib_perf, perf_print_details)(_perf_runtime_##id, PERF_COUNTER_GET_AVERAGE(id), PERF_COUNTER_GET_MIN(id), PERF_COUNTER_GET_MAX(id), _perf_calls_##id, PERF_PROFILING_OUTPUT_PREFIX(__FILE__, __FUNCTION__, __LINE__, x))
// Performance arrays
#define PERF_SET_ARRAYS ((ulong)((ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_array), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters), 512) > NULL) && (ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_min), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters), 512) > NULL) && ((LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)LIB_DBG_NAMESPACE(lib_perf, perf_counters) - 1] = ULONG_MAX) > 0x00) && (ArrayResize(LIB_DBG_NAMESPACE(lib_perf, perf_max), (int)LIB_DBG_NAMESPACE(lib_perf, perf_counters), 512) > 0x00) && ((LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)LIB_DBG_NAMESPACE(lib_perf, perf_counters) - 1] = 0x00) == 0x00)))
#define PERF_UPDATE_COUNTERS(x) LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] += _perf_runtime_##x; LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] = (((LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] > _perf_runtime_##x) || (LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x] == 0x00)) ? _perf_runtime_##x : LIB_DBG_NAMESPACE(lib_perf, perf_min)[(int)_perf_id_##x]); LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x] = ((LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x] < _perf_runtime_##x) ? _perf_runtime_##x : LIB_DBG_NAMESPACE(lib_perf, perf_max)[(int)_perf_id_##x]);
// Counter init
#define PERF_COUNTER_DEFINE_ID(x) const static ulong _perf_id_##x = LIB_DBG_NAMESPACE(lib_perf, perf_counters)++; static ulong _perf_start_##x = PERF_SET_ARRAYS; static ulong _perf_calls_##x = (LIB_DBG_NAMESPACE(lib_perf, perf_array)[(int)_perf_id_##x] = 0x00);
// Counter start
#define PERF_COUNTER_SET_ID(x) _perf_calls_##x++; _perf_start_##x = GetMicrosecondCount();
// Display performance counter
#define PERF_COUNTER_CLOSE_ID(id, x) { const ulong _perf_runtime_##id = (GetMicrosecondCount() - _perf_start_##id); PERF_UPDATE_COUNTERS(id); PERF_OUTPUT_FORMAT_ID(id, x); }
#define PERF_COUNTER_CLOSE(x) { const ulong _perf_runtime_##x = (GetMicrosecondCount() - _perf_start_##x); PERF_UPDATE_COUNTERS(x); PERF_OUTPUT_FORMAT_ID(x, " {...}; "); }
// Predefined function global performance counter macros
#define PERF_COUNTER_BEGIN PERF_COUNTER_DEFINE_ID(__FUNCTION__) PERF_COUNTER_SET_ID(__FUNCTION__)
#define PERF_COUNTER_END PERF_COUNTER_CLOSE(__FUNCTION__)
#define PERF_COUNTER_BEGIN_ID(x) PERF_COUNTER_SET_ID(x)
#define PERF_COUNTER_END_ID(x) PERF_COUNTER_CLOSE_ID(x, #x)
// Predefined standalone performance measurements
#define PERF_COUNTER_TIMEIT_V(x) do { PERF_COUNTER_DEFINE_ID(__LINE__); PERF_COUNTER_BEGIN_ID(__LINE__); x; PERF_COUNTER_CLOSE_ID(__LINE__, #x); } while(false)
#ifdef __MQL5__
#define PERF_COUNTER_TIMEIT_R(x) LIB_DBG_NAMESPACE(lib_perf, perf_R_call)(GetMicrosecondCount(), (x), GetMicrosecondCount(), __COUNTER__, #x, __FILE__, __FUNCTION__, __LINE__)
#define PERF_COUNTER_TIMEIT_O(x) LIB_DBG_NAMESPACE(lib_perf, perf_O_call)(GetMicrosecondCount(), (x), GetMicrosecondCount(), __COUNTER__, #x, __FILE__, __FUNCTION__, __LINE__)
#else
#define PERF_COUNTER_TIMEIT_R(x) LIB_DBG_NAMESPACE(lib_perf, perf_R_call)(GetMicrosecondCount(), (x), GetMicrosecondCount(), -1, #x, __FILE__, __FUNCTION__, __LINE__)
#define PERF_COUNTER_TIMEIT_O(x) LIB_DBG_NAMESPACE(lib_perf, perf_O_call)(GetMicrosecondCount(), (x), GetMicrosecondCount(), -1, #x, __FILE__, __FUNCTION__, __LINE__)
#endif
#endif
//
// END Debugging support
//*********************************************************************************************************************************************************/
#endif // LIB_DEBUG_MQH_INCLUDED