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
ac05c045
Commit
ac05c045
authored
May 23, 2016
by
Ismael
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor MinimalLEastSq
parent
5e52d2d6
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
93 additions
and
92 deletions
+93
-92
README.md
README.md
+2
-2
benchmark_api.h
include/benchmark/benchmark_api.h
+9
-9
reporter.h
include/benchmark/reporter.h
+1
-1
benchmark.cc
src/benchmark.cc
+3
-3
csv_reporter.cc
src/csv_reporter.cc
+3
-3
json_reporter.cc
src/json_reporter.cc
+3
-3
minimal_leastsq.cc
src/minimal_leastsq.cc
+47
-47
minimal_leastsq.h
src/minimal_leastsq.h
+5
-5
reporter.cc
src/reporter.cc
+9
-9
complexity_test.cc
test/complexity_test.cc
+11
-10
No files found.
README.md
View file @
ac05c045
...
...
@@ -127,14 +127,14 @@ static void BM_StringCompare(benchmark::State& state) {
benchmark
::
DoNotOptimize
(
s1
.
compare
(
s2
));
}
BENCHMARK
(
BM_StringCompare
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
18
)
->
Complexity
(
benchmark
::
O_
N
);
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
18
)
->
Complexity
(
benchmark
::
o
N
);
```
As shown in the following invocation, asymptotic complexity might also be calculated automatically.
```
c++
BENCHMARK
(
BM_StringCompare
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
18
)
->
Complexity
(
benchmark
::
O_
Auto
);
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
18
)
->
Complexity
(
benchmark
::
o
Auto
);
```
### Templated benchmarks
...
...
include/benchmark/benchmark_api.h
View file @
ac05c045
...
...
@@ -232,17 +232,17 @@ enum TimeUnit {
};
// BigO is passed to a benchmark in order to specify the asymptotic computational
// complexity for the benchmark. In case
O_
Auto is selected, complexity will be
// complexity for the benchmark. In case
o
Auto is selected, complexity will be
// calculated automatically to the best fit.
enum
BigO
{
O_
None
,
O_
1
,
O_
N
,
O_N_
Squared
,
O_N_
Cubed
,
O_log_
N
,
O_N_log_
N
,
O_
Auto
o
None
,
o
1
,
o
N
,
oN
Squared
,
oN
Cubed
,
oLog
N
,
oNLog
N
,
o
Auto
};
// State is passed to a running Benchmark and contains state for the
...
...
include/benchmark/reporter.h
View file @
ac05c045
...
...
@@ -49,7 +49,7 @@ class BenchmarkReporter {
bytes_per_second
(
0
),
items_per_second
(
0
),
max_heapbytes_used
(
0
),
complexity
(
O_
None
),
complexity
(
o
None
),
arg1
(
0
),
arg2
(
0
),
report_big_o
(
false
),
...
...
src/benchmark.cc
View file @
ac05c045
...
...
@@ -454,7 +454,7 @@ 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
),
complexity_
(
O_
None
)
{
complexity_
(
o
None
)
{
}
BenchmarkImp
::~
BenchmarkImp
()
{
...
...
@@ -803,7 +803,7 @@ void RunBenchmark(const benchmark::internal::Benchmark::Instance& b,
report
.
complexity
=
b
.
complexity
;
reports
.
push_back
(
report
);
if
(
report
.
complexity
!=
O_
None
)
if
(
report
.
complexity
!=
o
None
)
complexity_reports
.
push_back
(
report
);
break
;
...
...
@@ -830,7 +830,7 @@ void RunBenchmark(const benchmark::internal::Benchmark::Instance& b,
}
br
->
ReportRuns
(
reports
);
if
((
b
.
complexity
!=
O_
None
)
&&
b
.
last_benchmark_instance
)
{
if
((
b
.
complexity
!=
o
None
)
&&
b
.
last_benchmark_instance
)
{
br
->
ReportComplexity
(
complexity_reports
);
complexity_reports
.
clear
();
}
...
...
src/csv_reporter.cc
View file @
ac05c045
...
...
@@ -72,12 +72,12 @@ void CSVReporter::ReportComplexity(const std::vector<Run> & complexity_reports)
return
;
}
Run
big
O
_data
;
Run
big
_o
_data
;
Run
rms_data
;
BenchmarkReporter
::
ComputeBigO
(
complexity_reports
,
&
big
O
_data
,
&
rms_data
);
BenchmarkReporter
::
ComputeBigO
(
complexity_reports
,
&
big
_o
_data
,
&
rms_data
);
// Output using PrintRun.
PrintRunData
(
big
O
_data
);
PrintRunData
(
big
_o
_data
);
PrintRunData
(
rms_data
);
}
...
...
src/json_reporter.cc
View file @
ac05c045
...
...
@@ -127,13 +127,13 @@ void JSONReporter::ReportComplexity(const std::vector<Run> & complexity_reports)
out
<<
",
\n
"
;
}
Run
big
O
_data
;
Run
big
_o
_data
;
Run
rms_data
;
BenchmarkReporter
::
ComputeBigO
(
complexity_reports
,
&
big
O
_data
,
&
rms_data
);
BenchmarkReporter
::
ComputeBigO
(
complexity_reports
,
&
big
_o
_data
,
&
rms_data
);
// Output using PrintRun.
out
<<
indent
<<
"{
\n
"
;
PrintRunData
(
big
O
_data
);
PrintRunData
(
big
_o
_data
);
out
<<
indent
<<
"},
\n
"
;
out
<<
indent
<<
"{
\n
"
;
PrintRunData
(
rms_data
);
...
...
src/minimal_leastsq.cc
View file @
ac05c045
...
...
@@ -16,95 +16,94 @@
// Adapted to be used with google benchmark
#include "minimal_leastsq.h"
#include "check.h"
#include <math.h>
// Internal function to calculate the different scalability forms
double
f
ittingCurve
(
double
n
,
benchmark
::
BigO
complexity
)
{
double
F
ittingCurve
(
double
n
,
benchmark
::
BigO
complexity
)
{
switch
(
complexity
)
{
case
benchmark
:
:
O_
N
:
case
benchmark
:
:
o
N
:
return
n
;
case
benchmark
:
:
O_N_
Squared
:
case
benchmark
:
:
oN
Squared
:
return
pow
(
n
,
2
);
case
benchmark
:
:
O_N_
Cubed
:
case
benchmark
:
:
oN
Cubed
:
return
pow
(
n
,
3
);
case
benchmark
:
:
O_log_
N
:
case
benchmark
:
:
oLog
N
:
return
log2
(
n
);
case
benchmark
:
:
O_N_log_
N
:
case
benchmark
:
:
oNLog
N
:
return
n
*
log2
(
n
);
case
benchmark
:
:
O_
1
:
case
benchmark
:
:
o
1
:
default:
return
1
;
}
}
// Internal function to find the coefficient for the high-order term in the running time, by minimizing the sum of squares of relative error.
// -
N
: Vector containing the size of the benchmark tests.
// -
T
ime : Vector containing the times for the benchmark tests.
// -
C
omplexity : Fitting curve.
// -
n
: Vector containing the size of the benchmark tests.
// -
t
ime : Vector containing the times for the benchmark tests.
// -
c
omplexity : Fitting curve.
// For a deeper explanation on the algorithm logic, look the README file at http://github.com/ismaelJimenez/Minimal-Cpp-Least-Squared-Fit
LeastSq
leastSq
(
const
std
::
vector
<
int
>&
N
,
const
std
::
vector
<
double
>&
Time
,
const
benchmark
::
BigO
Complexity
)
{
assert
(
N
.
size
()
==
Time
.
size
()
&&
N
.
size
()
>=
2
);
assert
(
Complexity
!=
benchmark
::
O_None
&&
Complexity
!=
benchmark
::
O_Auto
);
LeastSq
CalculateLeastSq
(
const
std
::
vector
<
int
>&
n
,
const
std
::
vector
<
double
>&
time
,
const
benchmark
::
BigO
complexity
)
{
CHECK_NE
(
complexity
,
benchmark
::
oAuto
);
double
sigma
GN
=
0
;
double
sigma
GNS
quared
=
0
;
double
sigma
T
ime
=
0
;
double
sigma
TimeGN
=
0
;
double
sigma
_gn
=
0
;
double
sigma
_gn_s
quared
=
0
;
double
sigma
_t
ime
=
0
;
double
sigma
_time_gn
=
0
;
// Calculate least square fitting parameter
for
(
size_t
i
=
0
;
i
<
N
.
size
();
++
i
)
{
double
GNi
=
fittingCurve
(
N
[
i
],
C
omplexity
);
sigma
GN
+=
GN
i
;
sigma
GNSquared
+=
GNi
*
GN
i
;
sigma
Time
+=
T
ime
[
i
];
sigma
TimeGN
+=
Time
[
i
]
*
GN
i
;
for
(
size_t
i
=
0
;
i
<
n
.
size
();
++
i
)
{
double
gn_i
=
FittingCurve
(
n
[
i
],
c
omplexity
);
sigma
_gn
+=
gn_
i
;
sigma
_gn_squared
+=
gn_i
*
gn_
i
;
sigma
_time
+=
t
ime
[
i
];
sigma
_time_gn
+=
time
[
i
]
*
gn_
i
;
}
LeastSq
result
;
result
.
complexity
=
C
omplexity
;
result
.
complexity
=
c
omplexity
;
// Calculate complexity.
//
O_
1 is treated as an special case
if
(
Complexity
!=
benchmark
::
O_
1
)
result
.
coef
=
sigma
TimeGN
/
sigmaGNS
quared
;
//
o
1 is treated as an special case
if
(
complexity
!=
benchmark
::
o
1
)
result
.
coef
=
sigma
_time_gn
/
sigma_gn_s
quared
;
else
result
.
coef
=
sigma
Time
/
N
.
size
();
result
.
coef
=
sigma
_time
/
n
.
size
();
// Calculate RMS
double
rms
=
0
;
for
(
size_t
i
=
0
;
i
<
N
.
size
();
++
i
)
{
double
fit
=
result
.
coef
*
fittingCurve
(
N
[
i
],
C
omplexity
);
rms
+=
pow
((
T
ime
[
i
]
-
fit
),
2
);
for
(
size_t
i
=
0
;
i
<
n
.
size
();
++
i
)
{
double
fit
=
result
.
coef
*
FittingCurve
(
n
[
i
],
c
omplexity
);
rms
+=
pow
((
t
ime
[
i
]
-
fit
),
2
);
}
double
mean
=
sigma
Time
/
N
.
size
();
double
mean
=
sigma
_time
/
n
.
size
();
result
.
rms
=
sqrt
(
rms
/
N
.
size
())
/
mean
;
// Normalized RMS by the mean of the observed values
result
.
rms
=
sqrt
(
rms
/
n
.
size
())
/
mean
;
// Normalized RMS by the mean of the observed values
return
result
;
}
// Find the coefficient for the high-order term in the running time, by minimizing the sum of squares of relative error.
// -
N
: Vector containing the size of the benchmark tests.
// -
T
ime : Vector containing the times for the benchmark tests.
// -
Complexity : If different than O_Auto, the fitting curve will stick to this one. If it is O_
Auto, it will be calculated
// -
n
: Vector containing the size of the benchmark tests.
// -
t
ime : Vector containing the times for the benchmark tests.
// -
complexity : If different than oAuto, the fitting curve will stick to this one. If it is o
Auto, it will be calculated
// the best fitting curve.
LeastSq
minimalLeastSq
(
const
std
::
vector
<
int
>&
N
,
const
std
::
vector
<
double
>&
Time
,
const
benchmark
::
BigO
Complexity
)
{
assert
(
N
.
size
()
==
Time
.
size
()
&&
N
.
size
()
>=
2
);
// Do not compute fitting curve is less than two benchmark runs are given
assert
(
Complexity
!=
benchmark
::
O_None
);
// Check that complexity is a valid parameter.
LeastSq
MinimalLeastSq
(
const
std
::
vector
<
int
>&
n
,
const
std
::
vector
<
double
>&
time
,
const
benchmark
::
BigO
complexity
)
{
CHECK_EQ
(
n
.
size
(),
time
.
size
());
CHECK_GE
(
n
.
size
(),
2
);
// Do not compute fitting curve is less than two benchmark runs are given
CHECK_NE
(
complexity
,
benchmark
::
oNone
);
if
(
Complexity
==
benchmark
::
O_
Auto
)
{
std
::
vector
<
benchmark
::
BigO
>
fit
Curves
=
{
benchmark
::
O_log_N
,
benchmark
::
O_N
,
benchmark
::
O_N_log_N
,
benchmark
::
O_N_Squared
,
benchmark
::
O_N_
Cubed
};
if
(
complexity
==
benchmark
::
o
Auto
)
{
std
::
vector
<
benchmark
::
BigO
>
fit
_curves
=
{
benchmark
::
oLogN
,
benchmark
::
oN
,
benchmark
::
oNLogN
,
benchmark
::
oNSquared
,
benchmark
::
oN
Cubed
};
LeastSq
best_fit
=
leastSq
(
N
,
Time
,
benchmark
::
O_1
);
// Take O_
1 as default best fitting curve
LeastSq
best_fit
=
CalculateLeastSq
(
n
,
time
,
benchmark
::
o1
);
// Take o
1 as default best fitting curve
// Compute all possible fitting curves and stick to the best one
for
(
const
auto
&
fit
:
fit
C
urves
)
{
LeastSq
current_fit
=
leastSq
(
N
,
T
ime
,
fit
);
for
(
const
auto
&
fit
:
fit
_c
urves
)
{
LeastSq
current_fit
=
CalculateLeastSq
(
n
,
t
ime
,
fit
);
if
(
current_fit
.
rms
<
best_fit
.
rms
)
best_fit
=
current_fit
;
}
...
...
@@ -112,5 +111,5 @@ LeastSq minimalLeastSq(const std::vector<int>& N, const std::vector<double>& Tim
return
best_fit
;
}
else
return
leastSq
(
N
,
Time
,
C
omplexity
);
return
CalculateLeastSq
(
n
,
time
,
c
omplexity
);
}
\ No newline at end of file
src/minimal_leastsq.h
View file @
ac05c045
...
...
@@ -22,18 +22,18 @@
#include <vector>
// This data structure will contain the result returned by
m
inimalLeastSq
// This data structure will contain the result returned by
M
inimalLeastSq
// - coef : Estimated coeficient for the high-order term as interpolated from data.
// - rms : Normalized Root Mean Squared Error.
// - complexity : Scalability form (e.g.
O_N, O_N_log_N). In case a scalability form has been provided to m
inimalLeastSq
// this will return the same value. In case BigO::
O_
Auto has been selected, this parameter will return the
// - complexity : Scalability form (e.g.
oN, oNLogN). In case a scalability form has been provided to M
inimalLeastSq
// this will return the same value. In case BigO::
o
Auto has been selected, this parameter will return the
// best fitting curve detected.
struct
LeastSq
{
LeastSq
()
:
coef
(
0
),
rms
(
0
),
complexity
(
benchmark
::
O_
None
)
{}
complexity
(
benchmark
::
o
None
)
{}
double
coef
;
double
rms
;
...
...
@@ -41,6 +41,6 @@ struct LeastSq {
};
// 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
benchmark
::
BigO
Complexity
=
benchmark
::
O_
Auto
);
LeastSq
MinimalLeastSq
(
const
std
::
vector
<
int
>&
N
,
const
std
::
vector
<
double
>&
Time
,
const
benchmark
::
BigO
Complexity
=
benchmark
::
o
Auto
);
#endif
src/reporter.cc
View file @
ac05c045
...
...
@@ -95,13 +95,13 @@ void BenchmarkReporter::ComputeBigO(
CpuTime
.
push_back
(
run
.
cpu_accumulated_time
/
run
.
iterations
);
}
LeastSq
resultCpu
=
m
inimalLeastSq
(
N
,
CpuTime
,
reports
[
0
].
complexity
);
LeastSq
resultCpu
=
M
inimalLeastSq
(
N
,
CpuTime
,
reports
[
0
].
complexity
);
// resultCpu.complexity is passed as parameter to resultReal because in case
// reports[0].complexity is
O_
Auto, the noise on the measured data could make
// reports[0].complexity is
o
Auto, 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
resultReal
=
m
inimalLeastSq
(
N
,
RealTime
,
resultCpu
.
complexity
);
LeastSq
resultReal
=
M
inimalLeastSq
(
N
,
RealTime
,
resultCpu
.
complexity
);
std
::
string
benchmark_name
=
reports
[
0
].
benchmark_name
.
substr
(
0
,
reports
[
0
].
benchmark_name
.
find
(
'/'
));
...
...
@@ -130,17 +130,17 @@ void BenchmarkReporter::ComputeBigO(
std
::
string
BenchmarkReporter
::
GetBigO
(
BigO
complexity
)
{
switch
(
complexity
)
{
case
O_
N
:
case
o
N
:
return
"* N"
;
case
O_N_
Squared
:
case
oN
Squared
:
return
"* N**2"
;
case
O_N_
Cubed
:
case
oN
Cubed
:
return
"* N**3"
;
case
O_log_
N
:
case
oLog
N
:
return
"* lgN"
;
case
O_N_log_
N
:
case
oNLog
N
:
return
"* NlgN"
;
case
O_
1
:
case
o
1
:
return
"* 1"
;
default
:
return
""
;
...
...
test/complexity_test.cc
View file @
ac05c045
...
...
@@ -27,7 +27,7 @@ void BM_Complexity_O1(benchmark::State& state) {
while
(
state
.
KeepRunning
())
{
}
}
BENCHMARK
(
BM_Complexity_O1
)
->
Range
(
1
,
1
<<
18
)
->
Complexity
(
benchmark
::
O_
1
);
BENCHMARK
(
BM_Complexity_O1
)
->
Range
(
1
,
1
<<
18
)
->
Complexity
(
benchmark
::
o
1
);
static
void
BM_Complexity_O_N
(
benchmark
::
State
&
state
)
{
auto
v
=
ConstructRandomVector
(
state
.
range_x
());
...
...
@@ -36,8 +36,8 @@ static void BM_Complexity_O_N(benchmark::State& state) {
benchmark
::
DoNotOptimize
(
std
::
find
(
v
.
begin
(),
v
.
end
(),
itemNotInVector
));
}
}
BENCHMARK
(
BM_Complexity_O_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
O_
N
);
BENCHMARK
(
BM_Complexity_O_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
O_
Auto
);
BENCHMARK
(
BM_Complexity_O_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
o
N
);
BENCHMARK
(
BM_Complexity_O_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
o
Auto
);
static
void
BM_Complexity_O_N_Squared
(
benchmark
::
State
&
state
)
{
std
::
string
s1
(
state
.
range_x
(),
'-'
);
...
...
@@ -50,7 +50,7 @@ static void BM_Complexity_O_N_Squared(benchmark::State& state) {
}
}
}
BENCHMARK
(
BM_Complexity_O_N_Squared
)
->
Range
(
1
,
1
<<
8
)
->
Complexity
(
benchmark
::
O_N_
Squared
);
BENCHMARK
(
BM_Complexity_O_N_Squared
)
->
Range
(
1
,
1
<<
8
)
->
Complexity
(
benchmark
::
oN
Squared
);
static
void
BM_Complexity_O_N_Cubed
(
benchmark
::
State
&
state
)
{
std
::
string
s1
(
state
.
range_x
(),
'-'
);
...
...
@@ -67,7 +67,7 @@ static void BM_Complexity_O_N_Cubed(benchmark::State& state) {
}
}
}
BENCHMARK
(
BM_Complexity_O_N_Cubed
)
->
DenseRange
(
1
,
8
)
->
Complexity
(
benchmark
::
O_N_
Cubed
);
BENCHMARK
(
BM_Complexity_O_N_Cubed
)
->
DenseRange
(
1
,
8
)
->
Complexity
(
benchmark
::
oN
Cubed
);
static
void
BM_Complexity_O_log_N
(
benchmark
::
State
&
state
)
{
auto
m
=
ConstructRandomMap
(
state
.
range_x
());
...
...
@@ -77,7 +77,7 @@ static void BM_Complexity_O_log_N(benchmark::State& state) {
}
}
BENCHMARK
(
BM_Complexity_O_log_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
O_log_
N
);
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
oLog
N
);
static
void
BM_Complexity_O_N_log_N
(
benchmark
::
State
&
state
)
{
auto
v
=
ConstructRandomVector
(
state
.
range_x
());
...
...
@@ -85,15 +85,15 @@ static void BM_Complexity_O_N_log_N(benchmark::State& state) {
std
::
sort
(
v
.
begin
(),
v
.
end
());
}
}
BENCHMARK
(
BM_Complexity_O_N_log_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
O_N_log_
N
);
BENCHMARK
(
BM_Complexity_O_N_log_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
O_
Auto
);
BENCHMARK
(
BM_Complexity_O_N_log_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
oNLog
N
);
BENCHMARK
(
BM_Complexity_O_N_log_N
)
->
RangeMultiplier
(
2
)
->
Range
(
1
<<
10
,
1
<<
16
)
->
Complexity
(
benchmark
::
o
Auto
);
// Test benchmark with no range and check no complexity is calculated.
void
BM_Extreme_Cases
(
benchmark
::
State
&
state
)
{
while
(
state
.
KeepRunning
())
{
}
}
BENCHMARK
(
BM_Extreme_Cases
)
->
Complexity
(
benchmark
::
O_N_log_
N
);
BENCHMARK
(
BM_Extreme_Cases
)
->
Arg
(
42
)
->
Complexity
(
benchmark
::
O_
Auto
);
BENCHMARK
(
BM_Extreme_Cases
)
->
Complexity
(
benchmark
::
oNLog
N
);
BENCHMARK
(
BM_Extreme_Cases
)
->
Arg
(
42
)
->
Complexity
(
benchmark
::
o
Auto
);
BENCHMARK_MAIN
()
\ No newline at end of file
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