| Index: third_party/google_benchmark/src/stat.h
|
| diff --git a/third_party/google_benchmark/src/stat.h b/third_party/google_benchmark/src/stat.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..136c3aa8d61fdc7f250e64f519d4cbb826750372
|
| --- /dev/null
|
| +++ b/third_party/google_benchmark/src/stat.h
|
| @@ -0,0 +1,306 @@
|
| +#ifndef BENCHMARK_STAT_H_
|
| +#define BENCHMARK_STAT_H_
|
| +
|
| +#include <cmath>
|
| +#include <limits>
|
| +#include <ostream>
|
| +#include <type_traits>
|
| +
|
| +namespace benchmark {
|
| +
|
| +template <typename VType, typename NumType>
|
| +class Stat1;
|
| +
|
| +template <typename VType, typename NumType>
|
| +class Stat1MinMax;
|
| +
|
| +typedef Stat1<float, int64_t> Stat1_f;
|
| +typedef Stat1<double, int64_t> Stat1_d;
|
| +typedef Stat1MinMax<float, int64_t> Stat1MinMax_f;
|
| +typedef Stat1MinMax<double, int64_t> Stat1MinMax_d;
|
| +
|
| +template <typename VType>
|
| +class Vector2;
|
| +template <typename VType>
|
| +class Vector3;
|
| +template <typename VType>
|
| +class Vector4;
|
| +
|
| +template <typename VType, typename NumType>
|
| +class Stat1 {
|
| + public:
|
| + typedef Stat1<VType, NumType> Self;
|
| +
|
| + Stat1() { Clear(); }
|
| + // Create a sample of value dat and weight 1
|
| + explicit Stat1(const VType &dat) {
|
| + sum_ = dat;
|
| + sum_squares_ = Sqr(dat);
|
| + numsamples_ = 1;
|
| + }
|
| + // Create statistics for all the samples between begin (included)
|
| + // and end(excluded)
|
| + explicit Stat1(const VType *begin, const VType *end) {
|
| + Clear();
|
| + for (const VType *item = begin; item < end; ++item) {
|
| + (*this) += Stat1(*item);
|
| + }
|
| + }
|
| + // Create a sample of value dat and weight w
|
| + Stat1(const VType &dat, const NumType &w) {
|
| + sum_ = w * dat;
|
| + sum_squares_ = w * Sqr(dat);
|
| + numsamples_ = w;
|
| + }
|
| + // Copy operator
|
| + Stat1(const Self &stat) {
|
| + sum_ = stat.sum_;
|
| + sum_squares_ = stat.sum_squares_;
|
| + numsamples_ = stat.numsamples_;
|
| + }
|
| +
|
| + void Clear() {
|
| + numsamples_ = NumType();
|
| + sum_squares_ = sum_ = VType();
|
| + }
|
| +
|
| + Self &operator=(const Self &stat) {
|
| + sum_ = stat.sum_;
|
| + sum_squares_ = stat.sum_squares_;
|
| + numsamples_ = stat.numsamples_;
|
| + return (*this);
|
| + }
|
| + // Merge statistics from two sample sets.
|
| + Self &operator+=(const Self &stat) {
|
| + sum_ += stat.sum_;
|
| + sum_squares_ += stat.sum_squares_;
|
| + numsamples_ += stat.numsamples_;
|
| + return (*this);
|
| + }
|
| + // The operation opposite to +=
|
| + Self &operator-=(const Self &stat) {
|
| + sum_ -= stat.sum_;
|
| + sum_squares_ -= stat.sum_squares_;
|
| + numsamples_ -= stat.numsamples_;
|
| + return (*this);
|
| + }
|
| + // Multiply the weight of the set of samples by a factor k
|
| + Self &operator*=(const VType &k) {
|
| + sum_ *= k;
|
| + sum_squares_ *= k;
|
| + numsamples_ *= k;
|
| + return (*this);
|
| + }
|
| +
|
| + // Merge statistics from two sample sets.
|
| + Self operator+(const Self &stat) const { return Self(*this) += stat; }
|
| +
|
| + // The operation opposite to +
|
| + Self operator-(const Self &stat) const { return Self(*this) -= stat; }
|
| +
|
| + // Multiply the weight of the set of samples by a factor k
|
| + Self operator*(const VType &k) const { return Self(*this) *= k; }
|
| +
|
| + // Return the total weight of this sample set
|
| + NumType numSamples() const { return numsamples_; }
|
| +
|
| + // Return the sum of this sample set
|
| + VType Sum() const { return sum_; }
|
| +
|
| + // Return the mean of this sample set
|
| + VType Mean() const {
|
| + if (numsamples_ == 0) return VType();
|
| + return sum_ * (1.0 / numsamples_);
|
| + }
|
| +
|
| + // Return the mean of this sample set and compute the standard deviation at
|
| + // the same time.
|
| + VType Mean(VType *stddev) const {
|
| + if (numsamples_ == 0) return VType();
|
| + VType mean = sum_ * (1.0 / numsamples_);
|
| + if (stddev) {
|
| + VType avg_squares = sum_squares_ * (1.0 / numsamples_);
|
| + *stddev = Sqrt(avg_squares - Sqr(mean));
|
| + }
|
| + return mean;
|
| + }
|
| +
|
| + // Return the standard deviation of the sample set
|
| + VType StdDev() const {
|
| + if (numsamples_ == 0) return VType();
|
| + VType mean = Mean();
|
| + VType avg_squares = sum_squares_ * (1.0 / numsamples_);
|
| + return Sqrt(avg_squares - Sqr(mean));
|
| + }
|
| +
|
| + private:
|
| + static_assert(std::is_integral<NumType>::value &&
|
| + !std::is_same<NumType, bool>::value,
|
| + "NumType must be an integral type that is not bool.");
|
| + // Let i be the index of the samples provided (using +=)
|
| + // and weight[i],value[i] be the data of sample #i
|
| + // then the variables have the following meaning:
|
| + NumType numsamples_; // sum of weight[i];
|
| + VType sum_; // sum of weight[i]*value[i];
|
| + VType sum_squares_; // sum of weight[i]*value[i]^2;
|
| +
|
| + // Template function used to square a number.
|
| + // For a vector we square all components
|
| + template <typename SType>
|
| + static inline SType Sqr(const SType &dat) {
|
| + return dat * dat;
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector2<SType> Sqr(const Vector2<SType> &dat) {
|
| + return dat.MulComponents(dat);
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector3<SType> Sqr(const Vector3<SType> &dat) {
|
| + return dat.MulComponents(dat);
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector4<SType> Sqr(const Vector4<SType> &dat) {
|
| + return dat.MulComponents(dat);
|
| + }
|
| +
|
| + // Template function used to take the square root of a number.
|
| + // For a vector we square all components
|
| + template <typename SType>
|
| + static inline SType Sqrt(const SType &dat) {
|
| + // Avoid NaN due to imprecision in the calculations
|
| + if (dat < 0) return 0;
|
| + return sqrt(dat);
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector2<SType> Sqrt(const Vector2<SType> &dat) {
|
| + // Avoid NaN due to imprecision in the calculations
|
| + return Max(dat, Vector2<SType>()).Sqrt();
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector3<SType> Sqrt(const Vector3<SType> &dat) {
|
| + // Avoid NaN due to imprecision in the calculations
|
| + return Max(dat, Vector3<SType>()).Sqrt();
|
| + }
|
| +
|
| + template <typename SType>
|
| + static inline Vector4<SType> Sqrt(const Vector4<SType> &dat) {
|
| + // Avoid NaN due to imprecision in the calculations
|
| + return Max(dat, Vector4<SType>()).Sqrt();
|
| + }
|
| +};
|
| +
|
| +// Useful printing function
|
| +template <typename VType, typename NumType>
|
| +std::ostream &operator<<(std::ostream &out, const Stat1<VType, NumType> &s) {
|
| + out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
|
| + << " nsamples = " << s.NumSamples() << "}";
|
| + return out;
|
| +}
|
| +
|
| +// Stat1MinMax: same as Stat1, but it also
|
| +// keeps the Min and Max values; the "-"
|
| +// operator is disabled because it cannot be implemented
|
| +// efficiently
|
| +template <typename VType, typename NumType>
|
| +class Stat1MinMax : public Stat1<VType, NumType> {
|
| + public:
|
| + typedef Stat1MinMax<VType, NumType> Self;
|
| +
|
| + Stat1MinMax() { Clear(); }
|
| + // Create a sample of value dat and weight 1
|
| + explicit Stat1MinMax(const VType &dat) : Stat1<VType, NumType>(dat) {
|
| + max_ = dat;
|
| + min_ = dat;
|
| + }
|
| + // Create statistics for all the samples between begin (included)
|
| + // and end(excluded)
|
| + explicit Stat1MinMax(const VType *begin, const VType *end) {
|
| + Clear();
|
| + for (const VType *item = begin; item < end; ++item) {
|
| + (*this) += Stat1MinMax(*item);
|
| + }
|
| + }
|
| + // Create a sample of value dat and weight w
|
| + Stat1MinMax(const VType &dat, const NumType &w)
|
| + : Stat1<VType, NumType>(dat, w) {
|
| + max_ = dat;
|
| + min_ = dat;
|
| + }
|
| + // Copy operator
|
| + Stat1MinMax(const Self &stat) : Stat1<VType, NumType>(stat) {
|
| + max_ = stat.max_;
|
| + min_ = stat.min_;
|
| + }
|
| +
|
| + void Clear() {
|
| + Stat1<VType, NumType>::Clear();
|
| + if (std::numeric_limits<VType>::has_infinity) {
|
| + min_ = std::numeric_limits<VType>::infinity();
|
| + max_ = -std::numeric_limits<VType>::infinity();
|
| + } else {
|
| + min_ = std::numeric_limits<VType>::max();
|
| + max_ = std::numeric_limits<VType>::min();
|
| + }
|
| + }
|
| +
|
| + Self &operator=(const Self &stat) {
|
| + this->Stat1<VType, NumType>::operator=(stat);
|
| + max_ = stat.max_;
|
| + min_ = stat.min_;
|
| + return (*this);
|
| + }
|
| + // Merge statistics from two sample sets.
|
| + Self &operator+=(const Self &stat) {
|
| + this->Stat1<VType, NumType>::operator+=(stat);
|
| + if (stat.max_ > max_) max_ = stat.max_;
|
| + if (stat.min_ < min_) min_ = stat.min_;
|
| + return (*this);
|
| + }
|
| + // Multiply the weight of the set of samples by a factor k
|
| + Self &operator*=(const VType &stat) {
|
| + this->Stat1<VType, NumType>::operator*=(stat);
|
| + return (*this);
|
| + }
|
| + // Merge statistics from two sample sets.
|
| + Self operator+(const Self &stat) const { return Self(*this) += stat; }
|
| + // Multiply the weight of the set of samples by a factor k
|
| + Self operator*(const VType &k) const { return Self(*this) *= k; }
|
| +
|
| + // Return the maximal value in this sample set
|
| + VType Max() const { return max_; }
|
| + // Return the minimal value in this sample set
|
| + VType Min() const { return min_; }
|
| +
|
| + private:
|
| + // The - operation makes no sense with Min/Max
|
| + // unless we keep the full list of values (but we don't)
|
| + // make it private, and let it undefined so nobody can call it
|
| + Self &operator-=(const Self &stat); // senseless. let it undefined.
|
| +
|
| + // The operation opposite to -
|
| + Self operator-(const Self &stat) const; // senseless. let it undefined.
|
| +
|
| + // Let i be the index of the samples provided (using +=)
|
| + // and weight[i],value[i] be the data of sample #i
|
| + // then the variables have the following meaning:
|
| + VType max_; // max of value[i]
|
| + VType min_; // min of value[i]
|
| +};
|
| +
|
| +// Useful printing function
|
| +template <typename VType, typename NumType>
|
| +std::ostream &operator<<(std::ostream &out,
|
| + const Stat1MinMax<VType, NumType> &s) {
|
| + out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
|
| + << " nsamples = " << s.NumSamples() << " min = " << s.Min()
|
| + << " max = " << s.Max() << "}";
|
| + return out;
|
| +}
|
| +} // end namespace benchmark
|
| +
|
| +#endif // BENCHMARK_STAT_H_
|
|
|