MQLplus/lib_structures/lib_perfutils.mqh
super.admin 466f9ca5c5 convert
2025-05-30 16:09:52 +02:00

199 lines
7.4 KiB
MQL5

#ifndef LIB_MQLPLUS_PERF_UTILS_MQH_INCLUDED
#define LIB_MQLPLUS_PERF_UTILS_MQH_INCLUDED
#property version "1.0";
/**********************************************************************************
* Copyright (C) 2010-2022 Dominik Egert <info@freie-netze.de>
*
* 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 <typename T>
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