mirror of https://github.com/google/benchmark.git
Third step in moving towards adopting new timer semantics
This commit is contained in:
parent
f947cebe15
commit
a187aa0803
|
@ -3,7 +3,8 @@ include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
# Define the source files
|
# Define the source files
|
||||||
set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc"
|
set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc"
|
||||||
"log.cc" "sleep.cc" "sysinfo.cc" "walltime.cc")
|
"log.cc" "sleep.cc" "string_util.cc" "sysinfo.cc"
|
||||||
|
"walltime.cc")
|
||||||
# Determine the correct regular expression engine to use
|
# Determine the correct regular expression engine to use
|
||||||
if(HAVE_STD_REGEX)
|
if(HAVE_STD_REGEX)
|
||||||
set(RE_FILES "re_std.cc")
|
set(RE_FILES "re_std.cc")
|
||||||
|
|
107
src/benchmark.cc
107
src/benchmark.cc
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
#include "re.h"
|
#include "re.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "stat.h"
|
#include "stat.h"
|
||||||
|
#include "string_util.h"
|
||||||
#include "sysinfo.h"
|
#include "sysinfo.h"
|
||||||
#include "walltime.h"
|
#include "walltime.h"
|
||||||
|
|
||||||
|
@ -82,108 +83,6 @@ DECLARE_string(heap_check);
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
namespace {
|
namespace {
|
||||||
// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
|
|
||||||
const char kBigSIUnits[] = "kMGTPEZY";
|
|
||||||
// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.
|
|
||||||
const char kBigIECUnits[] = "KMGTPEZY";
|
|
||||||
// milli, micro, nano, pico, femto, atto, zepto, yocto.
|
|
||||||
const char kSmallSIUnits[] = "munpfazy";
|
|
||||||
|
|
||||||
// We require that all three arrays have the same size.
|
|
||||||
static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),
|
|
||||||
"SI and IEC unit arrays must be the same size");
|
|
||||||
static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
|
|
||||||
"Small SI and Big SI unit arrays must be the same size");
|
|
||||||
static const size_t kUnitsSize = arraysize(kBigSIUnits);
|
|
||||||
|
|
||||||
void ToExponentAndMantissa(double val, double thresh, int precision,
|
|
||||||
double one_k, std::string* mantissa, size_t* exponent) {
|
|
||||||
std::stringstream mantissa_stream;
|
|
||||||
|
|
||||||
if (val < 0) {
|
|
||||||
mantissa_stream << "-";
|
|
||||||
val = -val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust threshold so that it never excludes things which can't be rendered
|
|
||||||
// in 'precision' digits.
|
|
||||||
const double adjusted_threshold =
|
|
||||||
std::max(thresh, 1.0 / pow(10.0, precision));
|
|
||||||
const double big_threshold = adjusted_threshold * one_k;
|
|
||||||
const double small_threshold = adjusted_threshold;
|
|
||||||
|
|
||||||
if (val > big_threshold) {
|
|
||||||
// Positive powers
|
|
||||||
double scaled = val;
|
|
||||||
for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {
|
|
||||||
scaled /= one_k;
|
|
||||||
if (scaled <= big_threshold) {
|
|
||||||
mantissa_stream << scaled;
|
|
||||||
*exponent = i + 1;
|
|
||||||
*mantissa = mantissa_stream.str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mantissa_stream << val;
|
|
||||||
*exponent = 0;
|
|
||||||
} else if (val < small_threshold) {
|
|
||||||
// Negative powers
|
|
||||||
double scaled = val;
|
|
||||||
for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {
|
|
||||||
scaled *= one_k;
|
|
||||||
if (scaled >= small_threshold) {
|
|
||||||
mantissa_stream << scaled;
|
|
||||||
*exponent = -i - 1;
|
|
||||||
*mantissa = mantissa_stream.str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mantissa_stream << val;
|
|
||||||
*exponent = 0;
|
|
||||||
} else {
|
|
||||||
mantissa_stream << val;
|
|
||||||
*exponent = 0;
|
|
||||||
}
|
|
||||||
*mantissa = mantissa_stream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ExponentToPrefix(size_t exponent, bool iec) {
|
|
||||||
if (exponent == 0) return "";
|
|
||||||
|
|
||||||
const size_t index = (exponent > 0 ? exponent - 1 : -exponent - 1);
|
|
||||||
if (index >= kUnitsSize) return "";
|
|
||||||
|
|
||||||
const char* array =
|
|
||||||
(exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);
|
|
||||||
if (iec)
|
|
||||||
return array[index] + std::string("i");
|
|
||||||
else
|
|
||||||
return std::string(1, array[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToBinaryStringFullySpecified(double value, double threshold,
|
|
||||||
int precision) {
|
|
||||||
std::string mantissa;
|
|
||||||
size_t exponent;
|
|
||||||
ToExponentAndMantissa(value, threshold, precision, 1024.0, &mantissa,
|
|
||||||
&exponent);
|
|
||||||
return mantissa + ExponentToPrefix(exponent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AppendHumanReadable(int n, std::string* str) {
|
|
||||||
std::stringstream ss;
|
|
||||||
// Round down to the nearest SI prefix.
|
|
||||||
ss << "/" << ToBinaryStringFullySpecified(n, 1.0, 0);
|
|
||||||
*str += ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::string HumanReadableNumber(double n) {
|
|
||||||
// 1.1 means that figures up to 1.1k should be shown with the next unit down;
|
|
||||||
// this softens edge effects.
|
|
||||||
// 1 means that we should show one decimal place of precision.
|
|
||||||
return ToBinaryStringFullySpecified(n, 1.1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
|
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
|
||||||
static const int kRangeMultiplier = 8;
|
static const int kRangeMultiplier = 8;
|
||||||
|
|
||||||
|
@ -271,7 +170,7 @@ void ComputeStats(const std::vector<BenchmarkReporter::Run>& reports,
|
||||||
mean_data->iterations;
|
mean_data->iterations;
|
||||||
mean_data->bytes_per_second = bytes_per_second_stat.Mean();
|
mean_data->bytes_per_second = bytes_per_second_stat.Mean();
|
||||||
mean_data->items_per_second = items_per_second_stat.Mean();
|
mean_data->items_per_second = items_per_second_stat.Mean();
|
||||||
mean_data->max_heapbytes_used = max_heapbytes_used_stat.max();
|
mean_data->max_heapbytes_used = max_heapbytes_used_stat.Max();
|
||||||
|
|
||||||
// Only add label to mean/stddev if it is same for all runs
|
// Only add label to mean/stddev if it is same for all runs
|
||||||
mean_data->report_label = reports[0].report_label;
|
mean_data->report_label = reports[0].report_label;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -14,9 +14,10 @@
|
||||||
|
|
||||||
#include "colorprint.h"
|
#include "colorprint.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "commandlineflags.h"
|
#include "commandlineflags.h"
|
||||||
|
#include "internal_macros.h"
|
||||||
|
|
||||||
DECLARE_bool(color_print);
|
DECLARE_bool(color_print);
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
#include "commandlineflags.h"
|
#include "commandlineflags.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
@ -75,10 +74,7 @@ bool ParseDouble(const std::string& src_text, const char* str, double* value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* GetEnv(const char* name) {
|
inline const char* GetEnv(const char* name) {
|
||||||
#if GTEST_OS_WINDOWS_MOBILE
|
#if defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
|
||||||
// We are on Windows CE, which has no environment variables.
|
|
||||||
return NULL;
|
|
||||||
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
|
|
||||||
// Environment variables which we programmatically clear will be set to the
|
// Environment variables which we programmatically clear will be set to the
|
||||||
// empty string rather than unset (NULL). Handle that case.
|
// empty string rather than unset (NULL). Handle that case.
|
||||||
const char* const env = getenv(name);
|
const char* const env = getenv(name);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef BENCHMARK_COMMANDLINEFLAGS_H_
|
#ifndef BENCHMARK_COMMANDLINEFLAGS_H_
|
||||||
#define BENCHMARK_COMMANDLINEFLAGS_H_
|
#define BENCHMARK_COMMANDLINEFLAGS_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Macro for referencing flags.
|
// Macro for referencing flags.
|
||||||
|
@ -72,6 +71,6 @@ bool ParseStringFlag(const char* str, const char* flag, std::string* value);
|
||||||
// Returns true if the string matches the flag.
|
// Returns true if the string matches the flag.
|
||||||
bool IsFlag(const char* str, const char* flag);
|
bool IsFlag(const char* str, const char* flag);
|
||||||
|
|
||||||
} // end namespace gbenchmark
|
} // end namespace benchmark
|
||||||
|
|
||||||
#endif // BENCHMARK_COMMANDLINEFLAGS_H_
|
#endif // BENCHMARK_COMMANDLINEFLAGS_H_
|
||||||
|
|
|
@ -21,7 +21,10 @@
|
||||||
#ifndef BENCHMARK_CYCLECLOCK_H_
|
#ifndef BENCHMARK_CYCLECLOCK_H_
|
||||||
#define BENCHMARK_CYCLECLOCK_H_
|
#define BENCHMARK_CYCLECLOCK_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "benchmark/macros.h"
|
||||||
|
#include "internal_macros.h"
|
||||||
|
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX)
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
|
@ -39,8 +42,6 @@ extern "C" uint64_t __rdtsc();
|
||||||
#endif
|
#endif
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "benchmark/macros.h"
|
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
// NOTE: only i386 and x86_64 have been well tested.
|
// NOTE: only i386 and x86_64 have been well tested.
|
||||||
// PPC, sparc, alpha, and ia64 are based on
|
// PPC, sparc, alpha, and ia64 are based on
|
||||||
|
|
2
src/re.h
2
src/re.h
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -12,7 +12,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <benchmark/macros.h>
|
|
||||||
#include "re.h"
|
#include "re.h"
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -14,8 +14,10 @@
|
||||||
|
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <cerrno>
|
||||||
#include <errno.h>
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "internal_macros.h"
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
#ifdef OS_WINDOWS
|
#ifdef OS_WINDOWS
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef BENCHMARK_SLEEP_H_
|
#ifndef BENCHMARK_SLEEP_H_
|
||||||
#define BENCHMARK_SLEEP_H_
|
#define BENCHMARK_SLEEP_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
const int64_t kNumMillisPerSecond = 1000LL;
|
const int64_t kNumMillisPerSecond = 1000LL;
|
||||||
|
|
11
src/stat.h
11
src/stat.h
|
@ -1,11 +1,12 @@
|
||||||
#ifndef BENCHMARK_STAT_H_
|
#ifndef BENCHMARK_STAT_H_
|
||||||
#define BENCHMARK_STAT_H_
|
#define BENCHMARK_STAT_H_
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <ostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
|
|
||||||
template <typename VType, typename NumType>
|
template <typename VType, typename NumType>
|
||||||
class Stat1;
|
class Stat1;
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ class Stat1 {
|
||||||
NumType numSamples() const { return numsamples_; }
|
NumType numSamples() const { return numsamples_; }
|
||||||
|
|
||||||
// Return the sum of this sample set
|
// Return the sum of this sample set
|
||||||
VType sum() const { return sum_; }
|
VType Sum() const { return sum_; }
|
||||||
|
|
||||||
// Return the mean of this sample set
|
// Return the mean of this sample set
|
||||||
VType Mean() const {
|
VType Mean() const {
|
||||||
|
@ -267,9 +268,9 @@ class Stat1MinMax : public Stat1<VType, NumType> {
|
||||||
Self operator*(const VType &k) const { return Self(*this) *= k; }
|
Self operator*(const VType &k) const { return Self(*this) *= k; }
|
||||||
|
|
||||||
// Return the maximal value in this sample set
|
// Return the maximal value in this sample set
|
||||||
VType max() const { return max_; }
|
VType Max() const { return max_; }
|
||||||
// Return the minimal value in this sample set
|
// Return the minimal value in this sample set
|
||||||
VType min() const { return min_; }
|
VType Min() const { return min_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The - operation makes no sense with Min/Max
|
// The - operation makes no sense with Min/Max
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#include "string_util.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "arraysize.h"
|
||||||
|
|
||||||
|
namespace benchmark {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
|
||||||
|
const char kBigSIUnits[] = "kMGTPEZY";
|
||||||
|
// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.
|
||||||
|
const char kBigIECUnits[] = "KMGTPEZY";
|
||||||
|
// milli, micro, nano, pico, femto, atto, zepto, yocto.
|
||||||
|
const char kSmallSIUnits[] = "munpfazy";
|
||||||
|
|
||||||
|
// We require that all three arrays have the same size.
|
||||||
|
static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),
|
||||||
|
"SI and IEC unit arrays must be the same size");
|
||||||
|
static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
|
||||||
|
"Small SI and Big SI unit arrays must be the same size");
|
||||||
|
|
||||||
|
static const int kUnitsSize = arraysize(kBigSIUnits);
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
void ToExponentAndMantissa(double val, double thresh, int precision,
|
||||||
|
double one_k, std::string* mantissa,
|
||||||
|
int* exponent) {
|
||||||
|
std::stringstream mantissa_stream;
|
||||||
|
|
||||||
|
if (val < 0) {
|
||||||
|
mantissa_stream << "-";
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust threshold so that it never excludes things which can't be rendered
|
||||||
|
// in 'precision' digits.
|
||||||
|
const double adjusted_threshold =
|
||||||
|
std::max(thresh, 1.0 / std::pow(10.0, precision));
|
||||||
|
const double big_threshold = adjusted_threshold * one_k;
|
||||||
|
const double small_threshold = adjusted_threshold;
|
||||||
|
|
||||||
|
if (val > big_threshold) {
|
||||||
|
// Positive powers
|
||||||
|
double scaled = val;
|
||||||
|
for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {
|
||||||
|
scaled /= one_k;
|
||||||
|
if (scaled <= big_threshold) {
|
||||||
|
mantissa_stream << scaled;
|
||||||
|
*exponent = i + 1;
|
||||||
|
*mantissa = mantissa_stream.str();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mantissa_stream << val;
|
||||||
|
*exponent = 0;
|
||||||
|
} else if (val < small_threshold) {
|
||||||
|
// Negative powers
|
||||||
|
double scaled = val;
|
||||||
|
for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {
|
||||||
|
scaled *= one_k;
|
||||||
|
if (scaled >= small_threshold) {
|
||||||
|
mantissa_stream << scaled;
|
||||||
|
*exponent = -i - 1;
|
||||||
|
*mantissa = mantissa_stream.str();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mantissa_stream << val;
|
||||||
|
*exponent = 0;
|
||||||
|
} else {
|
||||||
|
mantissa_stream << val;
|
||||||
|
*exponent = 0;
|
||||||
|
}
|
||||||
|
*mantissa = mantissa_stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExponentToPrefix(int exponent, bool iec) {
|
||||||
|
if (exponent == 0) return "";
|
||||||
|
|
||||||
|
const int index = (exponent > 0 ? exponent - 1 : -exponent - 1);
|
||||||
|
if (index >= kUnitsSize) return "";
|
||||||
|
|
||||||
|
const char* array =
|
||||||
|
(exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);
|
||||||
|
if (iec)
|
||||||
|
return array[index] + std::string("i");
|
||||||
|
else
|
||||||
|
return std::string(1, array[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToBinaryStringFullySpecified(double value, double threshold,
|
||||||
|
int precision) {
|
||||||
|
std::string mantissa;
|
||||||
|
int exponent;
|
||||||
|
ToExponentAndMantissa(value, threshold, precision, 1024.0, &mantissa,
|
||||||
|
&exponent);
|
||||||
|
return mantissa + ExponentToPrefix(exponent, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendHumanReadable(int n, std::string* str) {
|
||||||
|
std::stringstream ss;
|
||||||
|
// Round down to the nearest SI prefix.
|
||||||
|
ss << "/" << ToBinaryStringFullySpecified(n, 1.0, 0);
|
||||||
|
*str += ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string HumanReadableNumber(double n) {
|
||||||
|
// 1.1 means that figures up to 1.1k should be shown with the next unit down;
|
||||||
|
// this softens edge effects.
|
||||||
|
// 1 means that we should show one decimal place of precision.
|
||||||
|
return ToBinaryStringFullySpecified(n, 1.1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringPrintFImp(const char *msg, va_list args)
|
||||||
|
{
|
||||||
|
// we might need a second shot at this, so pre-emptivly make a copy
|
||||||
|
va_list args_cp;
|
||||||
|
va_copy(args_cp, args);
|
||||||
|
|
||||||
|
// TODO(ericwf): use std::array for first attempt to avoid one memory
|
||||||
|
// allocation guess what the size might be
|
||||||
|
std::array<char, 256> local_buff;
|
||||||
|
std::size_t size = local_buff.size();
|
||||||
|
auto ret = std::vsnprintf(local_buff.data(), size, msg, args_cp);
|
||||||
|
|
||||||
|
va_end(args_cp);
|
||||||
|
|
||||||
|
// handle empty expansion
|
||||||
|
if (ret == 0)
|
||||||
|
return std::string{};
|
||||||
|
if (static_cast<std::size_t>(ret) < size)
|
||||||
|
return std::string(local_buff.data());
|
||||||
|
|
||||||
|
// we did not provide a long enough buffer on our first attempt.
|
||||||
|
// add 1 to size to account for null-byte in size cast to prevent overflow
|
||||||
|
size = static_cast<std::size_t>(ret) + 1;
|
||||||
|
auto buff_ptr = std::unique_ptr<char[]>(new char[size]);
|
||||||
|
ret = std::vsnprintf(buff_ptr.get(), size, msg, args);
|
||||||
|
return std::string(buff_ptr.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StringPrintF(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
std::string tmp = StringPrintFImp(format, args);
|
||||||
|
va_end(args);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace benchmark
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef BENCHMARK_STRING_UTIL_H
|
||||||
|
#define BENCHMARK_STRING_UTIL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace benchmark {
|
||||||
|
|
||||||
|
void ToExponentAndMantissa(double val, double thresh, int precision,
|
||||||
|
double one_k, std::string* mantissa, int* exponent);
|
||||||
|
|
||||||
|
std::string ExponentToPrefix(int exponent, bool iec);
|
||||||
|
|
||||||
|
std::string ToBinaryStringFullySpecified(double value, double threshold,
|
||||||
|
int precision);
|
||||||
|
|
||||||
|
void AppendHumanReadable(int n, std::string* str);
|
||||||
|
|
||||||
|
std::string HumanReadableNumber(double n);
|
||||||
|
|
||||||
|
std::string StringPrintF(const char* format, ...);
|
||||||
|
|
||||||
|
inline std::ostream&
|
||||||
|
StringCatImp(std::ostream& out) noexcept
|
||||||
|
{
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class First, class ...Rest>
|
||||||
|
inline std::ostream&
|
||||||
|
StringCatImp(std::ostream& out, First&& f, Rest&&... rest)
|
||||||
|
{
|
||||||
|
out << std::forward<First>(f);
|
||||||
|
return StringCatImp(out, std::forward<Rest>(rest)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class ...Args>
|
||||||
|
inline std::string StrCat(Args&&... args)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
StringCatImp(ss, std::forward<Args>(args)...);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace benchmark
|
||||||
|
|
||||||
|
#endif // BENCHMARK_STRING_UTIL_H
|
|
@ -14,24 +14,26 @@
|
||||||
|
|
||||||
#include "sysinfo.h"
|
#include "sysinfo.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "arraysize.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "cycleclock.h"
|
#include "cycleclock.h"
|
||||||
|
#include "internal_macros.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
namespace benchmark {
|
namespace benchmark {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 Google Inc. All rights reserved.
|
// Copyright 2015 Google Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
Loading…
Reference in New Issue