From 590b159f14fd2057c4222cfc997e10cb296a56bf Mon Sep 17 00:00:00 2001 From: Lion Kortlepel Date: Thu, 7 Mar 2024 00:25:47 +0100 Subject: [PATCH] switch to a runnning calculation for stdev and mean --- include/Profiling.h | 11 ++++++++--- src/Profiling.cpp | 46 ++++++++++++--------------------------------- src/TLuaEngine.cpp | 2 +- src/main.cpp | 15 ++++++++++++++- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/include/Profiling.h b/include/Profiling.h index ad3e76b..68ece0b 100644 --- a/include/Profiling.h +++ b/include/Profiling.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace prof { @@ -18,7 +19,7 @@ Duration duration(const TimePoint& start, const TimePoint& end); struct Stats { double mean; - double stddev; + double stdev; double min; double max; size_t n; @@ -38,11 +39,15 @@ struct UnitExecutionTime { Stats stats() const; /// Returns the number of elements the moving average is calculated over. - size_t measurement_count(); + size_t measurement_count() const { return m_total_calls; } private: - boost::synchronized_value> m_measurements; size_t m_total_calls {}; + double m_sum {}; + // sum of measurements squared (for running stdev) + double m_measurement_sqr_sum {}; + double m_min { std::numeric_limits::max() }; + double m_max { std::numeric_limits::min() }; }; /// Holds profiles for multiple units by name. Threadsafe. diff --git a/src/Profiling.cpp b/src/Profiling.cpp index 1e17992..2e840c4 100644 --- a/src/Profiling.cpp +++ b/src/Profiling.cpp @@ -19,50 +19,28 @@ void prof::UnitProfileCollection::add_sample(const std::string& unit, const Dura m_map->operator[](unit).add_sample(duration); } -size_t prof::UnitExecutionTime::measurement_count() { - return m_measurements->size(); -} - prof::Stats prof::UnitExecutionTime::stats() const { Stats result {}; // calculate sum - auto measurements = m_measurements.synchronize(); - if (measurements->size() == 0) { - return result; - } - result.n = measurements->size(); - result.max = std::numeric_limits::min(); - result.min = std::numeric_limits::max(); - Duration sum {}; - for (const auto& measurement : *measurements) { - if (measurement.count() > result.max) { - result.max = measurement.count(); - } - if (measurement.count() < result.min) { - result.min = measurement.count(); - } - sum += measurement; - } - // calculate mean - result.mean = (sum / measurements->size()).count(); - // calculate stddev - result.stddev = 0; - for (const auto& measurement : *measurements) { - // (measurements[i] - mean)^2 - result.stddev += std::pow(measurement.count() - result.mean, 2); - } - result.stddev = std::sqrt(result.stddev / double(measurements->size())); - result.total_calls = m_total_calls; + result.n = m_total_calls; + result.max = m_min; + result.min = m_max; + // calculate mean: mean = sum_x / n + result.mean = m_sum / double(m_total_calls); + // calculate stdev: stdev = sqrt((sum_x2 / n) - (mean * mean)) + result.stdev = std::sqrt((m_measurement_sqr_sum / double(result.n)) - (result.mean * result.mean)); return result; } void prof::UnitExecutionTime::add_sample(const Duration& dur) { - m_measurements->push_back(dur); + m_sum += dur.count(); + m_measurement_sqr_sum += dur.count() * dur.count(); + m_min = std::min(dur.count(), m_min); + m_max = std::max(dur.count(), m_max); ++m_total_calls; } -prof::UnitExecutionTime::UnitExecutionTime() - : m_measurements(boost::circular_buffer(100)) { +prof::UnitExecutionTime::UnitExecutionTime() { } std::unordered_map prof::UnitProfileCollection::all_stats() { diff --git a/src/TLuaEngine.cpp b/src/TLuaEngine.cpp index 298c352..4baaa37 100644 --- a/src/TLuaEngine.cpp +++ b/src/TLuaEngine.cpp @@ -856,7 +856,7 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, TLuaStateI for (const auto& [name, stat] : stats) { Result[name] = StateView.create_table(); Result[name]["mean"] = stat.mean; - Result[name]["stddev"] = stat.stddev; + Result[name]["stdev"] = stat.stdev; Result[name]["min"] = stat.min; Result[name]["max"] = stat.max; Result[name]["n"] = stat.n; diff --git a/src/main.cpp b/src/main.cpp index 311fa26..bd08b75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,7 @@ #include "Common.h" #include "Http.h" #include "LuaAPI.h" +#include "Profiling.h" #include "SignalHandling.h" #include "TConfig.h" #include "THeartbeatThread.h" @@ -30,6 +31,7 @@ #include "TResourceManager.h" #include "TServer.h" +#include #include #include @@ -124,7 +126,7 @@ int BeamMPServerMain(MainArguments Arguments) { } } } - + TConfig Config(ConfigPath); if (Config.Failed()) { @@ -176,6 +178,17 @@ int BeamMPServerMain(MainArguments Arguments) { Http::Server::THttpServerInstance HttpServerInstance {}; } + prof::UnitExecutionTime t {}; + for (size_t i = 0; i < 10'000'000; ++i) { + t.add_sample(std::chrono::seconds(1)); + t.add_sample(std::chrono::seconds(2)); + t.add_sample(std::chrono::seconds(3)); + } + auto stats = t.stats(); + beammp_errorf("mean: {}, stdev: {}, min: {}, max: {}, n: {}", stats.mean, stats.stdev, stats.min, stats.max, stats.n); + + exit(69); + Application::SetSubsystemStatus("Main", Application::Status::Good); RegisterThread("Main(Waiting)");