/*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef FOLLY_BENCHMARK_H_
-#define FOLLY_BENCHMARK_H_
+#pragma once
#include <folly/Portability.h>
#include <folly/Preprocessor.h> // for FB_ANONYMOUS_VARIABLE
+#include <folly/ScopeGuard.h>
+#include <folly/portability/GFlags.h>
+#include <folly/portability/Time.h>
+
#include <cassert>
#include <ctime>
#include <boost/function_types/function_arity.hpp>
#include <functional>
#include <glog/logging.h>
-#include <gflags/gflags.h>
#include <limits>
+#include <type_traits>
DECLARE_bool(benchmark);
assert(end.tv_nsec >= start.tv_nsec);
return end.tv_nsec - start.tv_nsec;
}
- assert(end.tv_sec > start.tv_sec &&
- end.tv_sec - start.tv_sec <
+ assert(end.tv_sec > start.tv_sec);
+ auto diff = uint64_t(end.tv_sec - start.tv_sec);
+ assert(diff <
std::numeric_limits<uint64_t>::max() / 1000000000UL);
- return (end.tv_sec - start.tv_sec) * 1000000000UL
+ return diff * 1000000000UL
+ end.tv_nsec - start.tv_nsec;
}
}
BenchmarkSuspender(const BenchmarkSuspender &) = delete;
- BenchmarkSuspender(BenchmarkSuspender && rhs) {
+ BenchmarkSuspender(BenchmarkSuspender && rhs) noexcept {
start = rhs.start;
rhs.start.tv_nsec = rhs.start.tv_sec = 0;
}
CHECK_EQ(0, clock_gettime(detail::DEFAULT_CLOCK_ID, &start));
}
+ template <class F>
+ auto dismissing(F f) -> typename std::result_of<F()>::type {
+ SCOPE_EXIT { rehire(); };
+ dismiss();
+ return f();
+ }
+
/**
- * This helps the macro definition. To get around the dangers of
- * operator bool, returns a pointer to member (which allows no
- * arithmetic).
+ * This is for use inside of if-conditions, used in BENCHMARK macros.
+ * If-conditions bypass the explicit on operator bool.
*/
- operator int BenchmarkSuspender::*() const {
- return nullptr;
+ explicit operator bool() const {
+ return false;
}
/**
#pragma optimize("", on)
+#elif defined(__clang__)
+
+template <class T>
+__attribute__((__optnone__)) void doNotOptimizeAway(T&& /* datum */) {}
+
#else
+
template <class T>
void doNotOptimizeAway(T&& datum) {
asm volatile("" : "+r" (datum));
}
+
#endif
} // namespace folly
static unsigned funName(paramType paramName)
/**
- * Introduces a benchmark function. Use with either one one or two
- * arguments. The first is the name of the benchmark. Use something
- * descriptive, such as insertVectorBegin. The second argument may be
- * missing, or could be a symbolic counter. The counter dictates how
- * many internal iteration the benchmark does. Example:
+ * Introduces a benchmark function. Use with either one or two arguments.
+ * The first is the name of the benchmark. Use something descriptive, such
+ * as insertVectorBegin. The second argument may be missing, or could be a
+ * symbolic counter. The counter dictates how many internal iteration the
+ * benchmark does. Example:
*
* BENCHMARK(vectorPushBack) {
* vector<int> v;
BENCHMARK_NAMED_PARAM(name, param, param)
/**
- * Same as BENCHMARK_PARAM, but allows to return the actual number of
+ * Same as BENCHMARK_PARAM, but allows one to return the actual number of
* iterations that have been run.
*/
#define BENCHMARK_PARAM_MULTI(name, param) \
}
/**
- * Same as BENCHMARK_NAMED_PARAM, but allows to return the actual number
+ * Same as BENCHMARK_NAMED_PARAM, but allows one to return the actual number
* of iterations that have been run.
*/
#define BENCHMARK_NAMED_PARAM_MULTI(name, param_name, ...) \
__VA_ARGS__)
/**
- * Same as BENCHMARK_RELATIVE, but allows to return the actual number
+ * Same as BENCHMARK_RELATIVE, but allows one to return the actual number
* of iterations that have been run.
*/
#define BENCHMARK_RELATIVE_MULTI(name, ...) \
BENCHMARK_RELATIVE_NAMED_PARAM(name, param, param)
/**
- * Same as BENCHMARK_RELATIVE_PARAM, but allows to return the actual
+ * Same as BENCHMARK_RELATIVE_PARAM, but allows one to return the actual
* number of iterations that have been run.
*/
#define BENCHMARK_RELATIVE_PARAM_MULTI(name, param) \
}
/**
- * Same as BENCHMARK_RELATIVE_NAMED_PARAM, but allows to return the
+ * Same as BENCHMARK_RELATIVE_NAMED_PARAM, but allows one to return the
* actual number of iterations that have been run.
*/
#define BENCHMARK_RELATIVE_NAMED_PARAM_MULTI(name, param_name, ...) \
if (auto FB_ANONYMOUS_VARIABLE(BENCHMARK_SUSPEND) = \
::folly::BenchmarkSuspender()) {} \
else
-
-#endif // FOLLY_BENCHMARK_H_