84 lines
6.5 KiB
MQL5
84 lines
6.5 KiB
MQL5
#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
|