mirror of https://github.com/google/benchmark.git
Added test file and Complexity() interface
This commit is contained in:
parent
0a60062b3e
commit
27f0baa190
|
@ -231,6 +231,20 @@ enum TimeUnit {
|
|||
kMillisecond
|
||||
};
|
||||
|
||||
// BigO is passed to a benchmark in order to specify the asymptotic computational
|
||||
// complexity for the benchmark.
|
||||
enum BigO {
|
||||
O_None,
|
||||
O_1,
|
||||
O_N,
|
||||
O_M_plus_N,
|
||||
O_N_Squared,
|
||||
O_N_Cubed,
|
||||
O_log_N,
|
||||
O_N_log_N,
|
||||
O_Auto
|
||||
};
|
||||
|
||||
// State is passed to a running Benchmark and contains state for the
|
||||
// benchmark to use.
|
||||
class State {
|
||||
|
@ -465,6 +479,10 @@ public:
|
|||
// to control how many iterations are run, and in the printing of items/second
|
||||
// or MB/second values.
|
||||
Benchmark* UseManualTime();
|
||||
|
||||
// Set the asymptotic computational complexity for the benchmark. This option
|
||||
// called the asymptotic computational complexity will be shown on the output.
|
||||
Benchmark* Complexity(BigO complexity);
|
||||
|
||||
// Support for running multiple copies of the same benchmark concurrently
|
||||
// in multiple threads. This may be useful when measuring the scaling
|
||||
|
|
|
@ -290,6 +290,7 @@ struct Benchmark::Instance {
|
|||
int range_multiplier;
|
||||
bool use_real_time;
|
||||
bool use_manual_time;
|
||||
BigO complexity;
|
||||
double min_time;
|
||||
int threads; // Number of concurrent threads to use
|
||||
bool multithreaded; // Is benchmark multi-threaded?
|
||||
|
@ -331,6 +332,7 @@ public:
|
|||
void MinTime(double n);
|
||||
void UseRealTime();
|
||||
void UseManualTime();
|
||||
void Complexity(BigO complexity);
|
||||
void Threads(int t);
|
||||
void ThreadRange(int min_threads, int max_threads);
|
||||
void ThreadPerCpu();
|
||||
|
@ -349,6 +351,7 @@ private:
|
|||
double min_time_;
|
||||
bool use_real_time_;
|
||||
bool use_manual_time_;
|
||||
BigO complexity_;
|
||||
std::vector<int> thread_counts_;
|
||||
|
||||
BenchmarkImp& operator=(BenchmarkImp const&);
|
||||
|
@ -411,6 +414,7 @@ bool BenchmarkFamilies::FindBenchmarks(
|
|||
instance.min_time = family->min_time_;
|
||||
instance.use_real_time = family->use_real_time_;
|
||||
instance.use_manual_time = family->use_manual_time_;
|
||||
instance.complexity = family->complexity_;
|
||||
instance.threads = num_threads;
|
||||
instance.multithreaded = !(family->thread_counts_.empty());
|
||||
|
||||
|
@ -447,7 +451,8 @@ bool BenchmarkFamilies::FindBenchmarks(
|
|||
BenchmarkImp::BenchmarkImp(const char* name)
|
||||
: name_(name), arg_count_(-1), time_unit_(kNanosecond),
|
||||
range_multiplier_(kRangeMultiplier), min_time_(0.0),
|
||||
use_real_time_(false), use_manual_time_(false) {
|
||||
use_real_time_(false), use_manual_time_(false),
|
||||
complexity_(O_None) {
|
||||
}
|
||||
|
||||
BenchmarkImp::~BenchmarkImp() {
|
||||
|
@ -523,6 +528,10 @@ void BenchmarkImp::UseManualTime() {
|
|||
use_manual_time_ = true;
|
||||
}
|
||||
|
||||
void BenchmarkImp::Complexity(BigO complexity){
|
||||
complexity_ = complexity;
|
||||
}
|
||||
|
||||
void BenchmarkImp::Threads(int t) {
|
||||
CHECK_GT(t, 0);
|
||||
thread_counts_.push_back(t);
|
||||
|
@ -636,6 +645,11 @@ Benchmark* Benchmark::UseManualTime() {
|
|||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Complexity(BigO complexity) {
|
||||
imp_->Complexity(complexity);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Threads(int t) {
|
||||
imp_->Threads(t);
|
||||
return this;
|
||||
|
|
|
@ -47,6 +47,9 @@ set_target_properties(cxx03_test
|
|||
PROPERTIES COMPILE_FLAGS "${CXX03_FLAGS}")
|
||||
add_test(cxx03 cxx03_test --benchmark_min_time=0.01)
|
||||
|
||||
compile_benchmark_test(complexity_test)
|
||||
add_test(complexity_benchmark complexity_test --benchmark_min_time=0.01)
|
||||
|
||||
# Add the coverage command(s)
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||
|
@ -66,7 +69,7 @@ if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage")
|
|||
COMMAND ${LCOV} -q -a before.lcov -a after.lcov --output-file final.lcov
|
||||
COMMAND ${LCOV} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov
|
||||
COMMAND ${GENHTML} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_BINARY_DIR}" -t benchmark
|
||||
DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test
|
||||
DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test complexity_test
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Running LCOV"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
#include "benchmark/benchmark_api.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
std::vector<int> ConstructRandomVector(int size) {
|
||||
std::vector<int> v;
|
||||
v.reserve(size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
v.push_back(rand() % size);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
std::map<int, int> ConstructRandomMap(int size) {
|
||||
std::map<int, int> m;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
m.insert(std::make_pair(rand() % size, rand() % size));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void BM_Complexity_O1(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O1) -> Range(1, 1<<17) -> Complexity(benchmark::O_1);
|
||||
|
||||
static void BM_Complexity_O_N(benchmark::State& state) {
|
||||
auto v = ConstructRandomVector(state.range_x());
|
||||
const int itemNotInVector = state.range_x()*2; // Test worst case scenario (item not in vector)
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(std::find(v.begin(), v.end(), itemNotInVector));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_N) -> Range(1, 1<<10) -> Complexity(benchmark::O_N);
|
||||
BENCHMARK(BM_Complexity_O_N) -> Range(1, 1<<10) -> Complexity(benchmark::O_Auto);
|
||||
|
||||
static void BM_Complexity_O_M_plus_N(benchmark::State& state) {
|
||||
std::string s1(state.range_x(), '-');
|
||||
std::string s2(state.range_x(), '-');
|
||||
while (state.KeepRunning())
|
||||
benchmark::DoNotOptimize(s1.compare(s2));
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_M_plus_N)
|
||||
->RangeMultiplier(2)->Range(1<<10, 1<<18) -> Complexity(benchmark::O_M_plus_N);
|
||||
|
||||
static void BM_Complexity_O_N_Squared(benchmark::State& state) {
|
||||
std::string s1(state.range_x(), '-');
|
||||
std::string s2(state.range_x(), '-');
|
||||
while (state.KeepRunning())
|
||||
for(char& c1 : s1) {
|
||||
for(char& c2 : s2) {
|
||||
benchmark::DoNotOptimize(c1 = 'a');
|
||||
benchmark::DoNotOptimize(c2 = 'b');
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_N_Squared) -> Range(1, 1<<8) -> Complexity(benchmark::O_N_Squared);
|
||||
|
||||
static void BM_Complexity_O_N_Cubed(benchmark::State& state) {
|
||||
std::string s1(state.range_x(), '-');
|
||||
std::string s2(state.range_x(), '-');
|
||||
std::string s3(state.range_x(), '-');
|
||||
while (state.KeepRunning())
|
||||
for(char& c1 : s1) {
|
||||
for(char& c2 : s2) {
|
||||
for(char& c3 : s3) {
|
||||
benchmark::DoNotOptimize(c1 = 'a');
|
||||
benchmark::DoNotOptimize(c2 = 'b');
|
||||
benchmark::DoNotOptimize(c3 = 'c');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_N_Cubed) -> DenseRange(1, 8) -> Complexity(benchmark::O_N_Cubed);
|
||||
|
||||
static void BM_Complexity_O_log_N(benchmark::State& state) {
|
||||
auto m = ConstructRandomMap(state.range_x());
|
||||
const int itemNotInVector = state.range_x()*2; // Test worst case scenario (item not in vector)
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(m.find(itemNotInVector));
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_log_N) -> Range(1, 1<<10) -> Complexity(benchmark::O_log_N);
|
||||
|
||||
static void BM_Complexity_O_N_log_N(benchmark::State& state) {
|
||||
auto v = ConstructRandomVector(state.range_x());
|
||||
while (state.KeepRunning()) {
|
||||
std::sort(v.begin(), v.end());
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Complexity_O_N_log_N) -> Range(1, 1<<16) -> Complexity(benchmark::O_N_log_N);
|
||||
BENCHMARK(BM_Complexity_O_N_log_N) -> Range(1, 1<<16) -> Complexity(benchmark::O_Auto);
|
||||
|
||||
// Test benchmark with no range. Complexity is always calculated as O(1).
|
||||
void BM_Extreme_Cases(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Extreme_Cases);
|
||||
BENCHMARK(BM_Extreme_Cases)->Arg(42);
|
||||
|
||||
BENCHMARK_MAIN()
|
Loading…
Reference in New Issue