#ifndef LIB_MQLPLUS_PERF_UTILS_MQH_INCLUDED #define LIB_MQLPLUS_PERF_UTILS_MQH_INCLUDED #property version "1.0"; /********************************************************************************** * Copyright (C) 2010-2022 Dominik Egert * * This file is the performance utilities include file. * * MQLplus, including this file may not be copied and/or distributed * without explecit permit by the author. * Author Dominik Egert / Freie Netze UG. ********************************************************************************** * * Version: 1.0 * State: production * * File information * ================ * * * */ #ifdef DBG_MSG_TRACE_FILE_LOADER DBG_MSG_TRACE_FILE_LOADER; #endif /*********************************************************************************************************************************************************/ /* */ /* MQLplus performance metric structures */ /* */ /*********************************************************************************************************************************************************/ /////////////////////////////////////// // // Average value metrics structure // template struct perf_average { private: T values[]; T sum; int cnt; int mask; int ptr; public: perf_average() : cnt (NULL), mask (0xFF), ptr (NULL) { }; ~perf_average() { ::ArrayFree(values); }; const T avg() { return(sum/cnt); }; void set_mask(const int p_in) { mask = 0x7FFFFFFF & p_in); ::ArrayResize(values, mask); }; const T operator+=(const T p_in) { cnt++; cnt &= mask; ptr = (ptr % mask) + 1; values[ptr] = p_in; }; }; /////////////////////////////////////// // // Performance metrics structure // struct perf_metric { private: // Local data ulong _micros; ulong last; ulong max; ulong max_ever; ulong min; ulong sum; ulong sum_ever; ulong cnt_ever; uchar cnt; // Memory alignment uchar _res1; ushort _res2; uint _res3; public: // Constructor perf_metric() : _micros (NULL), last (NULL), max (NULL), max_ever (NULL), min (LONG_MAX), sum (NULL), sum_ever (NULL), cnt_ever (NULL), cnt (NULL), _res1 (NULL), _res2 (NULL), _res3 (NULL) { }; perf_metric(const ulong start_micros) : _micros (start_micros), last (NULL), max (NULL), max_ever (NULL), min (LONG_MAX), sum (NULL), sum_ever (NULL), cnt_ever (NULL), cnt (NULL), _res1 (NULL), _res2 (NULL), _res3 (NULL) { }; // Reset counters void reset(const int start_micros = NULL) { _micros = (start_micros == NULL) ? ::GetMicrosecondCount() : start_micros; last = NULL; max = NULL; min = LONG_MAX; sum = NULL; cnt = NULL; }; // Update void update(const ulong start = NULL) { last = ::GetMicrosecondCount() - ((start == NULL) ? _micros : start); max = (last > max) ? last : max; max_ever = (last > max_ever) ? last : max_ever; min = (last < min) ? last : min; sum += last; sum_ever += last; cnt++; cnt_ever++; max = (last * (cnt == NULL)) + (max * (cnt > NULL)); min = (last * (cnt == NULL)) + (min * (cnt > NULL)); sum /= (1 + (cnt == NULL)); cnt += (128 * (cnt == NULL)); }; // Begin time measurement void set() { _micros = ::GetMicrosecondCount(); }; // State details void disable() { min = LONG_MAX; }; bool is_running() { return(min != LONG_MAX); }; string get_str() { return(::StringFormat("last: %llu; avg: %llu; avg_ever: %llu; min: %llu; max: %llu; max_ever: %llu", last, sum / (cnt + (cnt == NULL)), sum_ever / (cnt_ever + (cnt_ever == NULL)), min, max, max_ever)); }; ulong get_avg() { return(sum / (cnt + (cnt == NULL))); }; ulong get_avg_ever() { return(sum_ever / (cnt_ever + (cnt_ever == NULL))); }; ulong get_min() { return(min); }; ulong get_max() { return(max); }; ulong get_max_ever() { return(max_ever); }; ulong get_last() { return(last); }; }; // // END MQL data structures */ //*********************************************************************************************************************************************************/ #endif // LIB_MQLPLUS_PERF_UTILS_MQH_INCLUDED