DiSMEC++
|
This class manages a collection of named Statistics
objects.
More...
#include <collection.h>
Public Member Functions | |
void | declare_stat (stat_id_t index, StatisticMetaData meta) |
Declares a new statistics. Defines the corresponding index and name. More... | |
void | declare_tag (tag_id_t index, std::string name) |
Declares a new tag value. More... | |
void | register_stat (const std::string &name, std::unique_ptr< Statistics > stat) |
Registers a Statistics object to the named slot. More... | |
const std::vector< StatisticMetaData > & | get_statistics_meta () const |
Gets a vector with the declarations for all statistics. More... | |
const Statistics & | get_stat (const std::string &name) const |
Returns the Statistics object corresponding to the slot name . More... | |
TagContainer | get_tag_by_name (const std::string &name) const |
Gets the tag with the given name. More... | |
const std::vector< TagContainer > & | get_all_tags () const |
Gets a vector which contains all the tags owned by this collection. More... | |
void | provide_tags (const StatisticsCollection &other) |
Registers all the tags of the other collection as read-only tags in this collection. More... | |
void | enable (stat_id_t stat) |
Explicitly enable the collection of statistics for the given index. More... | |
void | disable (stat_id_t stat) |
Explicitly disable the collection of statistics for the given index. More... | |
bool | is_enabled (stat_id_t stat) const |
Quickly checks whether collection of data is enabled for the given statistics. More... | |
void | enable (const std::string &stat) |
Enables collecting data based on the name of a statistics. More... | |
void | disable (const std::string &stat) |
Disables collecting data based on the name of a statistics. More... | |
bool | has_stat (const std::string &name) const |
Returns whether a stat with the given name is declared. More... | |
bool | is_enabled_by_name (const std::string &name) const |
Checks whether gathering data is enabled based on the statistic's name. More... | |
template<class T , std::enable_if_t<!std::is_invocable_v< T >, bool > = true> | |
void | record (stat_id_t stat, T &&value) |
Records an already computed value. More... | |
template<class F , std::enable_if_t< std::is_invocable_v< F >, bool > = true> | |
void | record (stat_id_t stat, F &&callable) |
Records a value that is computed only when needed. More... | |
void | set_tag (tag_id_t tag, int value) |
Sets the tag to the given integer value. More... | |
Private Member Functions | |
template<class T > | |
void | do_record (int index, T &&value) |
Private Attributes | |
std::vector< bool > | m_Enabled |
std::vector< StatisticMetaData > | m_MetaData |
std::vector< std::unique_ptr< Statistics > > | m_Statistics |
std::vector< TagContainer > | m_TagValues |
std::unordered_map< std::string, TagContainer > | m_TagLookup |
This class manages a collection of named Statistics
objects.
The functionality of this class is designed to be performance efficient, but nonetheless it should not be used in the inner loops. It is further designed so that statistics collection can be disabled at runtime, in which case the performance impact should be almost negligible.
This is achieved by assigning each named statistics also an integer id, which is used in the performance critical code path, which consists of the is_enabled()
and record()
functions. The check whether a particular statistics shall be collected is performed by is_enabled()
, which is a simple lookup in a boolean vector, and defined in the header so that it can be inlined. The record()
functions first check if the statistics is enabled, and if not no further action is performed. They are also defined in the header, so this check will get inlined too. In all, if statistics are disabled, each call to record should boil down to an inlined access to a boolean vector. For anything but the innermost loops, this should be fast enough.
The actual gathering of the statistics requires an additional vector lookup, followed by a virtual function call into the actual statistics implementation. This should also not impose too much of a performance problem in most cases. A different situation arises if the statistics we want to gather is not calculated as part of the regular computations, and is expensive to calculate. For that purpose, there exists an overload of record()
that takes a callable as an argument, which is evaluated only if the statistics is enabled.
StatisticsCollection
, my strategy is to define the ids as constants at the beginning of the implementation file which uses the collection.For extracting the statistics, no knowledge of the ids is required. This is because we consider that process to be non-performance-critical, and as such we can perform lookups based on the statistic's name. This means that often that the IDs can be considered an implementation detail of the code that records the statistics, which can be hidden from consumer code.
Definition at line 47 of file collection.h.
void StatisticsCollection::declare_stat | ( | stat_id_t | index, |
StatisticMetaData | meta | ||
) |
Declares a new statistics. Defines the corresponding index and name.
The new statistics is disabled by default, and no Statistics
object that gathers its values is associated. This can be changed by calling register_stat()
. The indices and names need to be unique.
index | Index of the new statistics. |
meta | Metadata of the new statistics. |
std::invalid_argument | If a stat with the same name or id already has been declared. |
Definition at line 40 of file collection.cpp.
References m_Enabled, m_MetaData, m_Statistics, dismec::stats::StatisticMetaData::Name, dismec::ssize(), and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by TEST_CASE().
void StatisticsCollection::declare_tag | ( | tag_id_t | index, |
std::string | name | ||
) |
Declares a new tag value.
index | The unique index to be used for the tag. |
name | The unique name to be used for the tag. |
Definition at line 87 of file collection.cpp.
References dismec::stats::TagContainer::create_full_container(), m_TagLookup, m_TagValues, dismec::ssize(), and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by TEST_CASE().
void StatisticsCollection::disable | ( | const std::string & | stat | ) |
Disables collecting data based on the name of a statistics.
std::invalid_argument | if not such stat exists. |
Definition at line 36 of file collection.cpp.
References disable(), m_MetaData, and anonymous_namespace{collection.cpp}::str_to_id().
void StatisticsCollection::disable | ( | stats::stat_id_t | stat | ) |
Explicitly disable the collection of statistics for the given index.
Definition at line 18 of file collection.cpp.
References m_Enabled, and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by disable(), register_stat(), and TEST_CASE().
|
inlineprivate |
void StatisticsCollection::enable | ( | const std::string & | stat | ) |
Enables collecting data based on the name of a statistics.
std::invalid_argument | if not such stat exists. |
Definition at line 32 of file collection.cpp.
References enable(), m_MetaData, and anonymous_namespace{collection.cpp}::str_to_id().
void StatisticsCollection::enable | ( | stat_id_t | stat | ) |
Explicitly enable the collection of statistics for the given index.
Collection of data can only be enabled for statistics for which a corresponding Statistics
object has been provided using register_stat()
.
std::logic_error | If you try to enable collection of a statistic without a registered Statistics object. |
Definition at line 12 of file collection.cpp.
References m_Enabled, m_Statistics, and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by enable(), register_stat(), and TEST_CASE().
|
inline |
Gets a vector which contains all the tags owned by this collection.
Definition at line 101 of file collection.h.
References m_TagValues.
Referenced by TEST_CASE().
const Statistics & StatisticsCollection::get_stat | ( | const std::string & | name | ) | const |
Returns the Statistics
object corresponding to the slot name
.
std::invalid_argument | if name has not been declared, or has no assigned Statistics object. |
Definition at line 75 of file collection.cpp.
References m_MetaData, m_Statistics, and anonymous_namespace{collection.cpp}::str_to_id().
Referenced by TEST_CASE().
|
inline |
Gets a vector with the declarations for all statistics.
Definition at line 82 of file collection.h.
References m_MetaData.
Referenced by TEST_CASE().
TagContainer StatisticsCollection::get_tag_by_name | ( | const std::string & | name | ) | const |
Gets the tag with the given name.
Returns a TagContainer
whose value is a pointer to the interval value stored in this collection. Thus, any Statistics
object that needs a tag can lookup the tag by using the name in its setup phase, and then during recording only needs to use the TagContainer
to get the current value, which is much faster.
std::out_of_range | if name has neither been declared nor provided by another collection. |
Definition at line 105 of file collection.cpp.
References m_TagLookup.
Referenced by dismec::stats::TaggedStat::setup(), and TEST_CASE().
bool StatisticsCollection::has_stat | ( | const std::string & | name | ) | const |
Returns whether a stat with the given name is declared.
Definition at line 122 of file collection.cpp.
References m_MetaData.
Referenced by TEST_CASE().
|
inline |
Quickly checks whether collection of data is enabled for the given statistics.
This function is defined in the header so it can be inlined.
stat | The id of the statistics for which the check if performed. |
Definition at line 131 of file collection.h.
References m_Enabled, and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by dismec::stats::ScopeTimer::is_enabled(), is_enabled_by_name(), record(), and TEST_CASE().
bool StatisticsCollection::is_enabled_by_name | ( | const std::string & | name | ) | const |
Checks whether gathering data is enabled based on the statistic's name.
Because this function has to perform the lookup for the name, it is much slower than is_enabled()
. Therefore, even though it performs the exact same function, it has not been provided an overload, but given an extra, longer name to prevent accidental performance problems.
Definition at line 83 of file collection.cpp.
References is_enabled(), m_MetaData, and anonymous_namespace{collection.cpp}::str_to_id().
Referenced by TEST_CASE().
void StatisticsCollection::provide_tags | ( | const StatisticsCollection & | other | ) |
Registers all the tags of the other collection as read-only tags in this collection.
Read-only tags can be accessed by get_tag_by_name()
, so that statistics can use them in their setup, but cannot be modified by set_tag()
. They don't even have an associated tag_id inside this collection.
Definition at line 109 of file collection.cpp.
References m_TagLookup.
Referenced by TEST_CASE().
|
inline |
Records a value that is computed only when needed.
F | A callable type. Will typically be the type of same lambda. |
stat | The id of the stat to be recorded. |
callable | A callable that produces a value that is compatible with Statistics::record() . Will only be called if the statistics has been enabled. |
A typical usage example would look like this
Here, intermediate
is a value that is calculated as part of the regular program flow, but for recording statistics we need expensive_function(intermediate)
. The invocation of the callable
itself is wrapped into an immediately invoked lambda annotated as cold, so that the expensive calculation will not get inlined into the main program flow and slow down the code path when the statistics is disabled.
Definition at line 198 of file collection.h.
References dismec::l2_reg_sq_hinge_detail::__attribute__(), do_record(), is_enabled(), and dismec::opaque_int_type< Tag, T >::to_index().
|
inline |
Records an already computed value.
T | The type of the recorded value. Needs to be compatible with Statistics::record() . |
stat | The id of the stat for which the value is recorded. |
value | The actual data. |
Definition at line 174 of file collection.h.
References do_record(), is_enabled(), and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by dismec::stats::ScopeTimer::record_duration(), and TEST_CASE().
void StatisticsCollection::register_stat | ( | const std::string & | name, |
std::unique_ptr< Statistics > | stat | ||
) |
Registers a Statistics
object to the named slot.
This function can also be used to unregister a Statistics
by providing nullptr
as the second argument. In that case, the statistics is automatically disabled, otherwise it is enabled.
name | Name for which stat should be registered. |
stat | The Statistics object to register. |
std::invalid_argument | If no slot name has been declared, or if there already is a registered stat for the slot and stat is not nullptr . |
Definition at line 59 of file collection.cpp.
References disable(), enable(), m_MetaData, m_Statistics, and anonymous_namespace{collection.cpp}::str_to_id().
Referenced by TEST_CASE().
|
inline |
Sets the tag to the given integer value.
Definition at line 209 of file collection.h.
References m_TagValues, and dismec::opaque_int_type< Tag, T >::to_index().
Referenced by dismec::stats::Tracked::set_tag(), and TEST_CASE().
|
private |
Definition at line 224 of file collection.h.
Referenced by declare_stat(), disable(), enable(), is_enabled(), and dismec::stats::ScopeTimer::ScopeTimer().
|
private |
Definition at line 225 of file collection.h.
Referenced by declare_stat(), disable(), enable(), get_stat(), get_statistics_meta(), has_stat(), is_enabled_by_name(), and register_stat().
|
private |
Definition at line 226 of file collection.h.
Referenced by declare_stat(), do_record(), enable(), get_stat(), and register_stat().
|
private |
Definition at line 229 of file collection.h.
Referenced by declare_tag(), get_tag_by_name(), and provide_tags().
|
private |
Definition at line 228 of file collection.h.
Referenced by declare_tag(), get_all_tags(), and set_tag().