Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
benchmark
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
benchmark
Commits
867f9145
Commit
867f9145
authored
Jun 01, 2016
by
Ismael
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added lambdas to complexity report
parent
74a278e2
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
96 additions
and
67 deletions
+96
-67
benchmark_api.h
include/benchmark/benchmark_api.h
+11
-1
reporter.h
include/benchmark/reporter.h
+3
-2
benchmark.cc
src/benchmark.cc
+22
-7
complexity.cc
src/complexity.cc
+29
-38
complexity.h
src/complexity.h
+7
-13
console_reporter.cc
src/console_reporter.cc
+2
-2
csv_reporter.cc
src/csv_reporter.cc
+5
-2
json_reporter.cc
src/json_reporter.cc
+17
-2
complexity_test.cc
test/complexity_test.cc
+0
-0
No files found.
include/benchmark/benchmark_api.h
View file @
867f9145
...
...
@@ -152,6 +152,7 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include "macros.h"
...
...
@@ -247,9 +248,14 @@ enum BigO {
oNCubed
,
oLogN
,
oNLogN
,
oAuto
oAuto
,
oLambda
};
// BigOFunc is passed to a benchmark in order to specify the asymptotic
// computational complexity for the benchmark.
typedef
double
(
BigOFunc
)(
size_t
);
// State is passed to a running Benchmark and contains state for the
// benchmark to use.
class
State
{
...
...
@@ -538,6 +544,10 @@ public:
// the asymptotic computational complexity will be shown on the output.
Benchmark
*
Complexity
(
BigO
complexity
=
benchmark
::
oAuto
);
// Set the asymptotic computational complexity for the benchmark. If called
// the asymptotic computational complexity will be shown on the output.
Benchmark
*
Complexity
(
BigOFunc
*
complexity
);
// Support for running multiple copies of the same benchmark concurrently
// in multiple threads. This may be useful when measuring the scaling
// of some piece of code.
...
...
include/benchmark/reporter.h
View file @
867f9145
...
...
@@ -86,7 +86,8 @@ class BenchmarkReporter {
// Keep track of arguments to compute asymptotic complexity
BigO
complexity
;
int
complexity_n
;
BigOFunc
*
complexity_lambda
;
size_t
complexity_n
;
// Inform print function whether the current run is a complexity report
bool
report_big_o
;
...
...
@@ -159,7 +160,7 @@ class ConsoleReporter : public BenchmarkReporter {
virtual
bool
ReportContext
(
const
Context
&
context
);
virtual
void
ReportRuns
(
const
std
::
vector
<
Run
>&
reports
);
protected
:
protected
:
virtual
void
PrintRunData
(
const
Run
&
report
);
size_t
name_field_width_
;
...
...
src/benchmark.cc
View file @
867f9145
...
...
@@ -124,7 +124,7 @@ struct ThreadStats {
ThreadStats
()
:
bytes_processed
(
0
),
items_processed
(
0
),
complexity_n
(
0
)
{}
int64_t
bytes_processed
;
int64_t
items_processed
;
int
complexity_n
;
size_t
complexity_n
;
};
// Timer management class
...
...
@@ -311,6 +311,7 @@ struct Benchmark::Instance {
bool
use_real_time
;
bool
use_manual_time
;
BigO
complexity
;
BigOFunc
*
complexity_lambda
;
bool
last_benchmark_instance
;
int
repetitions
;
double
min_time
;
...
...
@@ -356,6 +357,7 @@ public:
void
UseRealTime
();
void
UseManualTime
();
void
Complexity
(
BigO
complexity
);
void
ComplexityLambda
(
BigOFunc
*
complexity
);
void
Threads
(
int
t
);
void
ThreadRange
(
int
min_threads
,
int
max_threads
);
void
ThreadPerCpu
();
...
...
@@ -376,6 +378,7 @@ private:
bool
use_real_time_
;
bool
use_manual_time_
;
BigO
complexity_
;
BigOFunc
*
complexity_lambda_
;
std
::
vector
<
int
>
thread_counts_
;
BenchmarkImp
&
operator
=
(
BenchmarkImp
const
&
);
...
...
@@ -440,6 +443,7 @@ bool BenchmarkFamilies::FindBenchmarks(
instance
.
use_real_time
=
family
->
use_real_time_
;
instance
.
use_manual_time
=
family
->
use_manual_time_
;
instance
.
complexity
=
family
->
complexity_
;
instance
.
complexity_lambda
=
family
->
complexity_lambda_
;
instance
.
threads
=
num_threads
;
instance
.
multithreaded
=
!
(
family
->
thread_counts_
.
empty
());
...
...
@@ -567,6 +571,10 @@ void BenchmarkImp::Complexity(BigO complexity){
complexity_
=
complexity
;
}
void
BenchmarkImp
::
ComplexityLambda
(
BigOFunc
*
complexity
)
{
complexity_lambda_
=
complexity
;
}
void
BenchmarkImp
::
Threads
(
int
t
)
{
CHECK_GT
(
t
,
0
);
thread_counts_
.
push_back
(
t
);
...
...
@@ -691,6 +699,12 @@ Benchmark* Benchmark::Complexity(BigO complexity) {
return
this
;
}
Benchmark
*
Benchmark
::
Complexity
(
BigOFunc
*
complexity
)
{
imp_
->
Complexity
(
oLambda
);
imp_
->
ComplexityLambda
(
complexity
);
return
this
;
}
Benchmark
*
Benchmark
::
Threads
(
int
t
)
{
imp_
->
Threads
(
t
);
return
this
;
...
...
@@ -849,6 +863,7 @@ void RunBenchmark(const benchmark::internal::Benchmark::Instance& b,
report
.
items_per_second
=
items_per_second
;
report
.
complexity_n
=
total
.
complexity_n
;
report
.
complexity
=
b
.
complexity
;
report
.
complexity_lambda
=
b
.
complexity_lambda
;
if
(
report
.
complexity
!=
oNone
)
complexity_reports
.
push_back
(
report
);
}
...
...
@@ -949,9 +964,9 @@ void State::SetLabel(const char* label) {
}
namespace
internal
{
namespace
{
namespace
{
void
RunMatchingBenchmarks
(
const
std
::
vector
<
Benchmark
::
Instance
>&
benchmarks
,
void
RunMatchingBenchmarks
(
const
std
::
vector
<
Benchmark
::
Instance
>&
benchmarks
,
BenchmarkReporter
*
reporter
)
{
CHECK
(
reporter
!=
nullptr
);
...
...
@@ -982,9 +997,9 @@ void RunMatchingBenchmarks(const std::vector<Benchmark::Instance>& benchmarks,
RunBenchmark
(
benchmark
,
reporter
,
complexity_reports
);
}
}
}
}
std
::
unique_ptr
<
BenchmarkReporter
>
GetDefaultReporter
()
{
std
::
unique_ptr
<
BenchmarkReporter
>
GetDefaultReporter
()
{
typedef
std
::
unique_ptr
<
BenchmarkReporter
>
PtrType
;
if
(
FLAGS_benchmark_format
==
"console"
)
{
return
PtrType
(
new
ConsoleReporter
);
...
...
@@ -996,9 +1011,9 @@ std::unique_ptr<BenchmarkReporter> GetDefaultReporter() {
std
::
cerr
<<
"Unexpected format: '"
<<
FLAGS_benchmark_format
<<
"'
\n
"
;
std
::
exit
(
1
);
}
}
}
}
// end namespace
}
// end namespace
}
// end namespace internal
size_t
RunSpecifiedBenchmarks
()
{
...
...
src/complexity.cc
View file @
867f9145
...
...
@@ -27,21 +27,21 @@
namespace
benchmark
{
// Internal function to calculate the different scalability forms
std
::
function
<
double
(
int
)
>
FittingCurve
(
BigO
complexity
)
{
BigOFunc
*
FittingCurve
(
BigO
complexity
)
{
switch
(
complexity
)
{
case
oN
:
return
[](
int
n
)
{
return
n
;
};
return
[](
size_t
n
)
->
double
{
return
n
;
};
case
oNSquared
:
return
[](
int
n
)
{
return
n
*
n
;
};
return
[](
size_t
n
)
->
double
{
return
n
*
n
;
};
case
oNCubed
:
return
[](
int
n
)
{
return
n
*
n
*
n
;
};
return
[](
size_t
n
)
->
double
{
return
n
*
n
*
n
;
};
case
oLogN
:
return
[](
in
t
n
)
{
return
log2
(
n
);
};
return
[](
size_
t
n
)
{
return
log2
(
n
);
};
case
oNLogN
:
return
[](
in
t
n
)
{
return
n
*
log2
(
n
);
};
return
[](
size_
t
n
)
{
return
n
*
log2
(
n
);
};
case
o1
:
default
:
return
[](
int
)
{
return
1
;
};
return
[](
size_t
)
{
return
1.0
;
};
}
}
...
...
@@ -49,19 +49,19 @@ std::function<double(int)> FittingCurve(BigO complexity) {
std
::
string
GetBigOString
(
BigO
complexity
)
{
switch
(
complexity
)
{
case
oN
:
return
"*
N"
;
return
"
N"
;
case
oNSquared
:
return
"* N**
2"
;
return
"N^
2"
;
case
oNCubed
:
return
"* N**
3"
;
return
"N^
3"
;
case
oLogN
:
return
"*
lgN"
;
return
"
lgN"
;
case
oNLogN
:
return
"*
NlgN"
;
return
"
NlgN"
;
case
o1
:
return
"* 1
"
;
return
"(1)
"
;
default
:
return
"
"
;
return
"f(N)
"
;
}
}
...
...
@@ -75,21 +75,9 @@ std::string GetBigOString(BigO complexity) {
// For a deeper explanation on the algorithm logic, look the README file at
// http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit
// This interface is currently not used from the oustide, but it has been
// provided for future upgrades. If in the future it is not needed to support
// Cxx03, then all the calculations could be upgraded to use lambdas because
// they are more powerful and provide a cleaner inferface than enumerators,
// but complete implementation with lambdas will not work for Cxx03
// (e.g. lack of std::function).
// In case lambdas are implemented, the interface would be like :
// -> Complexity([](int n) {return n;};)
// and any arbitrary and valid equation would be allowed, but the option to
// calculate the best fit to the most common scalability curves will still
// be kept.
LeastSq
CalculateLeastSq
(
const
std
::
vector
<
int
>&
n
,
LeastSq
MinimalLeastSq
(
const
std
::
vector
<
int
>&
n
,
const
std
::
vector
<
double
>&
time
,
std
::
function
<
double
(
int
)
>
fitting_curve
)
{
BigOFunc
*
fitting_curve
)
{
double
sigma_gn
=
0.0
;
double
sigma_gn_squared
=
0.0
;
double
sigma_time
=
0.0
;
...
...
@@ -105,6 +93,7 @@ LeastSq CalculateLeastSq(const std::vector<int>& n,
}
LeastSq
result
;
result
.
complexity
=
oLambda
;
// Calculate complexity.
result
.
coef
=
sigma_time_gn
/
sigma_gn_squared
;
...
...
@@ -144,19 +133,19 @@ LeastSq MinimalLeastSq(const std::vector<int>& n,
oLogN
,
oN
,
oNLogN
,
oNSquared
,
oNCubed
};
// Take o1 as default best fitting curve
best_fit
=
Calculate
LeastSq
(
n
,
time
,
FittingCurve
(
o1
));
best_fit
=
Minimal
LeastSq
(
n
,
time
,
FittingCurve
(
o1
));
best_fit
.
complexity
=
o1
;
// Compute all possible fitting curves and stick to the best one
for
(
const
auto
&
fit
:
fit_curves
)
{
LeastSq
current_fit
=
Calculate
LeastSq
(
n
,
time
,
FittingCurve
(
fit
));
LeastSq
current_fit
=
Minimal
LeastSq
(
n
,
time
,
FittingCurve
(
fit
));
if
(
current_fit
.
rms
<
best_fit
.
rms
)
{
best_fit
=
current_fit
;
best_fit
.
complexity
=
fit
;
}
}
}
else
{
best_fit
=
Calculate
LeastSq
(
n
,
time
,
FittingCurve
(
complexity
));
best_fit
=
Minimal
LeastSq
(
n
,
time
,
FittingCurve
(
complexity
));
best_fit
.
complexity
=
complexity
;
}
...
...
@@ -256,14 +245,16 @@ std::vector<BenchmarkReporter::Run> ComputeBigO(
cpu_time
.
push_back
(
run
.
cpu_accumulated_time
/
run
.
iterations
);
}
LeastSq
result_cpu
=
MinimalLeastSq
(
n
,
cpu_time
,
reports
[
0
].
complexity
);
// result_cpu.complexity is passed as parameter to result_real because in case
// reports[0].complexity is oAuto, the noise on the measured data could make
// the best fit function of Cpu and Real differ. In order to solve this, we
// take the best fitting function for the Cpu, and apply it to Real data.
LeastSq
result_real
=
MinimalLeastSq
(
n
,
real_time
,
result_cpu
.
complexity
);
LeastSq
result_cpu
;
LeastSq
result_real
;
if
(
reports
[
0
].
complexity
!=
oLambda
)
{
result_cpu
=
MinimalLeastSq
(
n
,
cpu_time
,
reports
[
0
].
complexity
);
result_real
=
MinimalLeastSq
(
n
,
real_time
,
result_cpu
.
complexity
);
}
else
{
result_cpu
=
MinimalLeastSq
(
n
,
cpu_time
,
reports
[
0
].
complexity_lambda
);
result_real
=
MinimalLeastSq
(
n
,
real_time
,
reports
[
0
].
complexity_lambda
);
}
std
::
string
benchmark_name
=
reports
[
0
].
benchmark_name
.
substr
(
0
,
reports
[
0
].
benchmark_name
.
find
(
'/'
));
// Get the data from the accumulator to BenchmarkReporter::Run's.
...
...
src/complexity.h
View file @
867f9145
...
...
@@ -26,15 +26,15 @@
namespace
benchmark
{
// Return a vector containing the mean and standard devation information for
// the specified list of reports. If 'reports' contains less than two
// non-errored runs an empty vector is returned
std
::
vector
<
BenchmarkReporter
::
Run
>
ComputeStats
(
// Return a vector containing the mean and standard devation information for
// the specified list of reports. If 'reports' contains less than two
// non-errored runs an empty vector is returned
std
::
vector
<
BenchmarkReporter
::
Run
>
ComputeStats
(
const
std
::
vector
<
BenchmarkReporter
::
Run
>&
reports
);
// Return a vector containing the bigO and RMS information for the specified
// list of reports. If 'reports.size() < 2' an empty vector is returned.
std
::
vector
<
BenchmarkReporter
::
Run
>
ComputeBigO
(
// Return a vector containing the bigO and RMS information for the specified
// list of reports. If 'reports.size() < 2' an empty vector is returned.
std
::
vector
<
BenchmarkReporter
::
Run
>
ComputeBigO
(
const
std
::
vector
<
BenchmarkReporter
::
Run
>&
reports
);
// This data structure will contain the result returned by MinimalLeastSq
...
...
@@ -60,11 +60,5 @@ struct LeastSq {
// Function to return an string for the calculated complexity
std
::
string
GetBigOString
(
BigO
complexity
);
// Find the coefficient for the high-order term in the running time, by
// minimizing the sum of squares of relative error.
LeastSq
MinimalLeastSq
(
const
std
::
vector
<
int
>&
n
,
const
std
::
vector
<
double
>&
time
,
const
BigO
complexity
=
oAuto
);
}
// end namespace benchmark
#endif // COMPLEXITY_H_
src/console_reporter.cc
View file @
867f9145
...
...
@@ -90,8 +90,8 @@ void ConsoleReporter::PrintRunData(const Run& result) {
const
double
cpu_time
=
result
.
GetAdjustedCPUTime
();
if
(
result
.
report_big_o
)
{
std
::
string
big_o
=
result
.
report_big_o
?
GetBigOString
(
result
.
complexity
)
:
""
;
ColorPrintf
(
Out
,
COLOR_YELLOW
,
"%10.
4f %s %10.4
f %s "
,
std
::
string
big_o
=
GetBigOString
(
result
.
complexity
)
;
ColorPrintf
(
Out
,
COLOR_YELLOW
,
"%10.
2f %s %10.2
f %s "
,
real_time
,
big_o
.
c_str
(),
cpu_time
,
big_o
.
c_str
());
}
else
if
(
result
.
report_rms
)
{
ColorPrintf
(
Out
,
COLOR_YELLOW
,
"%10.0f %% %10.0f %% "
,
...
...
src/csv_reporter.cc
View file @
867f9145
...
...
@@ -13,6 +13,7 @@
// limitations under the License.
#include "benchmark/reporter.h"
#include "complexity.h"
#include <cstdint>
#include <algorithm>
...
...
@@ -87,8 +88,10 @@ void CSVReporter::PrintRunData(const Run & run) {
Out
<<
run
.
GetAdjustedRealTime
()
<<
","
;
Out
<<
run
.
GetAdjustedCPUTime
()
<<
","
;
// Do not print timeLabel on RMS report
if
(
!
run
.
report_rms
)
{
// Do not print timeLabel on bigO and RMS report
if
(
run
.
report_big_o
)
{
Out
<<
GetBigOString
(
run
.
complexity
);
}
else
if
(
!
run
.
report_rms
){
Out
<<
GetTimeUnitString
(
run
.
time_unit
);
}
Out
<<
","
;
...
...
src/json_reporter.cc
View file @
867f9145
...
...
@@ -13,6 +13,7 @@
// limitations under the License.
#include "benchmark/reporter.h"
#include "complexity.h"
#include <cstdint>
#include <algorithm>
...
...
@@ -132,15 +133,29 @@ void JSONReporter::PrintRunData(Run const& run) {
out
<<
indent
<<
FormatKV
(
"iterations"
,
run
.
iterations
)
<<
",
\n
"
;
}
out
<<
indent
<<
FormatKV
(
"real_time"
,
RoundDouble
(
run
.
GetAdjustedRealTime
()))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"cpu_time"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()));
if
(
!
run
.
report_rms
)
{
out
<<
",
\n
"
<<
indent
<<
FormatKV
(
"time_unit"
,
GetTimeUnitString
(
run
.
time_unit
));
}
else
if
(
run
.
report_big_o
)
{
out
<<
indent
<<
FormatKV
(
"cpu_coefficient"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"real_coefficient"
,
RoundDouble
(
run
.
GetAdjustedRealTime
()))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"big_o"
,
GetBigOString
(
run
.
complexity
))
<<
",
\n
"
;
out
<<
indent
<<
FormatKV
(
"time_unit"
,
GetTimeUnitString
(
run
.
time_unit
));
}
else
if
(
run
.
report_rms
)
{
out
<<
indent
<<
FormatKV
(
"rms"
,
RoundDouble
(
run
.
GetAdjustedCPUTime
()
*
100
))
<<
"%"
;
}
if
(
run
.
bytes_per_second
>
0.0
)
{
out
<<
",
\n
"
<<
indent
...
...
test/complexity_test.cc
View file @
867f9145
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment