grouped cumulative_stats summarization in one operation

This commit is contained in:
joaquintides
2024-05-01 16:34:53 +02:00
parent 5feb7459ee
commit d01ae76074
2 changed files with 53 additions and 41 deletions

View File

@ -27,14 +27,7 @@ namespace detail{
* running sequences. * running sequences.
*/ */
struct cumulative_stats_summary struct sequence_stats_data
{
double average;
double variance;
double deviation;
};
struct cumulative_stats_data
{ {
double m=0.0; double m=0.0;
double m_prior=0.0; double m_prior=0.0;
@ -44,7 +37,7 @@ struct cumulative_stats_data
struct welfords_algorithm /* 0-based */ struct welfords_algorithm /* 0-based */
{ {
template<typename T> template<typename T>
int operator()(T&& x,cumulative_stats_data& d)const noexcept int operator()(T&& x,sequence_stats_data& d)const noexcept
{ {
static_assert( static_assert(
noexcept(static_cast<double>(x)), noexcept(static_cast<double>(x)),
@ -61,14 +54,27 @@ struct welfords_algorithm /* 0-based */
std::size_t n; std::size_t n;
}; };
struct sequence_stats_summary
{
double average;
double variance;
double deviation;
};
/* Stats calculated jointly for N same-sized sequences to save the space /* Stats calculated jointly for N same-sized sequences to save the space
* for n. * for count.
*/ */
template<std::size_t N> template<std::size_t N>
class cumulative_stats class cumulative_stats
{ {
public: public:
struct summary
{
std::size_t count;
std::array<sequence_stats_summary,N> sequence_summary;
};
void reset()noexcept{*this=cumulative_stats();} void reset()noexcept{*this=cumulative_stats();}
template<typename... Ts> template<typename... Ts>
@ -87,20 +93,22 @@ public:
data); data);
} }
std::size_t count()const noexcept{return n;} summary get_summary()const noexcept
template<std::size_t I>
cumulative_stats_summary get_summary()const noexcept
{ {
double average=data[I].m, summary res;
variance=n!=0?data[I].s/static_cast<double>(n):0.0, /* biased */ res.count=n;
deviation=std::sqrt(variance); for(std::size_t i=0;i<N;++i){
return {average,variance,deviation}; double average=data[i].m,
variance=n!=0?data[i].s/static_cast<double>(n):0.0, /* biased */
deviation=std::sqrt(variance);
res.sequence_summary[i]={average,variance,deviation};
}
return res;
} }
private: private:
std::size_t n=0; std::size_t n=0;
std::array<cumulative_stats_data,N> data; std::array<sequence_stats_data,N> data;
}; };
#if defined(BOOST_HAS_THREADS) #if defined(BOOST_HAS_THREADS)
@ -112,6 +120,8 @@ class concurrent_cumulative_stats:cumulative_stats<N>
using lock_guard=std::lock_guard<std::mutex>; using lock_guard=std::lock_guard<std::mutex>;
public: public:
using summary=super::summary;
concurrent_cumulative_stats()noexcept:super{}{} concurrent_cumulative_stats()noexcept:super{}{}
concurrent_cumulative_stats(const concurrent_cumulative_stats& x)noexcept: concurrent_cumulative_stats(const concurrent_cumulative_stats& x)noexcept:
concurrent_cumulative_stats{x,lock_guard{x.mut}}{} concurrent_cumulative_stats{x,lock_guard{x.mut}}{}
@ -138,11 +148,10 @@ public:
super::add(std::forward<Ts>(xs)...); super::add(std::forward<Ts>(xs)...);
} }
template<std::size_t I> summary get_summary()const noexcept
cumulative_stats_summary get_summary()const noexcept
{ {
lock_guard lck{mut}; lock_guard lck{mut};
return super::template get_summary<I>(); return super::get_summary();
} }
private: private:

View File

@ -1135,22 +1135,22 @@ struct table_arrays
struct table_core_cumulative_stats struct table_core_cumulative_stats
{ {
cumulative_stats<1> insertion; concurrent_cumulative_stats<1> insertion;
cumulative_stats<2> successful_lookup, concurrent_cumulative_stats<2> successful_lookup,
unsuccessful_lookup; unsuccessful_lookup;
}; };
struct table_core_insertion_stats struct table_core_insertion_stats
{ {
std::size_t count; std::size_t count;
cumulative_stats_summary probe_length; sequence_stats_summary probe_length;
}; };
struct table_core_lookup_stats struct table_core_lookup_stats
{ {
std::size_t count; std::size_t count;
cumulative_stats_summary probe_length; sequence_stats_summary probe_length;
cumulative_stats_summary num_comparisons; sequence_stats_summary num_comparisons;
}; };
struct table_core_stats struct table_core_stats
@ -1809,21 +1809,24 @@ public:
#if defined(BOOST_UNORDERED_ENABLE_STATS) #if defined(BOOST_UNORDERED_ENABLE_STATS)
stats get_stats()const stats get_stats()const
{ {
return { auto insertion=cstats.insertion.get_summary();
auto successful_lookup=cstats.successful_lookup.get_summary();
auto unsuccessful_lookup=cstats.unsuccessful_lookup.get_summary();
return{
{ {
cstats.insertion.count(), insertion.count,
cstats.insertion.get_summary<0>() insertion.sequence_summary[0]
}, },
{ {
cstats.successful_lookup.count(), successful_lookup.count,
cstats.successful_lookup.get_summary<0>(), successful_lookup.sequence_summary[0],
cstats.successful_lookup.get_summary<1>() successful_lookup.sequence_summary[1]
}, },
{ {
cstats.unsuccessful_lookup.count(), unsuccessful_lookup.count,
cstats.unsuccessful_lookup.get_summary<0>(), unsuccessful_lookup.sequence_summary[0],
cstats.unsuccessful_lookup.get_summary<1>() unsuccessful_lookup.sequence_summary[1]
} },
}; };
} }