Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
4a32903c
Commit
4a32903c
authored
Mar 26, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separate benchmark cases into separate binaries in order to compare binary sizes for each case.
parent
98873d06
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1504 additions
and
440 deletions
+1504
-440
capnproto-carsales.c++
c++/src/capnproto/benchmark/capnproto-carsales.c++
+140
-0
capnproto-catrank.c++
c++/src/capnproto/benchmark/capnproto-catrank.c++
+143
-0
capnproto-common.h
c++/src/capnproto/benchmark/capnproto-common.h
+0
-0
capnproto-eval.c++
c++/src/capnproto/benchmark/capnproto-eval.c++
+125
-0
carsales.capnp
c++/src/capnproto/benchmark/carsales.capnp
+0
-40
carsales.proto
c++/src/capnproto/benchmark/carsales.proto
+0
-36
catrank.capnp
c++/src/capnproto/benchmark/catrank.capnp
+32
-0
catrank.proto
c++/src/capnproto/benchmark/catrank.proto
+34
-0
common.h
c++/src/capnproto/benchmark/common.h
+9
-26
eval.capnp
c++/src/capnproto/benchmark/eval.capnp
+48
-0
eval.proto
c++/src/capnproto/benchmark/eval.proto
+46
-0
null-carsales.c++
c++/src/capnproto/benchmark/null-carsales.c++
+0
-0
null-catrank.c++
c++/src/capnproto/benchmark/null-catrank.c++
+171
-0
null-common.h
c++/src/capnproto/benchmark/null-common.h
+162
-0
null-eval.c++
c++/src/capnproto/benchmark/null-eval.c++
+157
-0
protobuf-carsales.c++
c++/src/capnproto/benchmark/protobuf-carsales.c++
+141
-0
protobuf-catrank.c++
c++/src/capnproto/benchmark/protobuf-catrank.c++
+131
-0
protobuf-common.h
c++/src/capnproto/benchmark/protobuf-common.h
+1
-304
protobuf-eval.c++
c++/src/capnproto/benchmark/protobuf-eval.c++
+120
-0
runner.c++
c++/src/capnproto/benchmark/runner.c++
+44
-34
No files found.
c++/src/capnproto/benchmark/capnproto-carsales.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "carsales.capnp.h"
#include "capnproto-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
capnp
{
template
<
typename
ReaderOrBuilder
>
uint64_t
carValue
(
ReaderOrBuilder
car
)
{
// Do not think too hard about realism.
uint64_t
result
=
0
;
result
+=
car
.
getSeats
()
*
200
;
result
+=
car
.
getDoors
()
*
350
;
for
(
auto
wheel
:
car
.
getWheels
())
{
result
+=
wheel
.
getDiameter
()
*
wheel
.
getDiameter
();
result
+=
wheel
.
getSnowTires
()
?
100
:
0
;
}
result
+=
car
.
getLength
()
*
car
.
getWidth
()
*
car
.
getHeight
()
/
50
;
auto
engine
=
car
.
getEngine
();
result
+=
engine
.
getHorsepower
()
*
40
;
if
(
engine
.
getUsesElectric
())
{
if
(
engine
.
getUsesGas
())
{
// hybrid
result
+=
5000
;
}
else
{
result
+=
3000
;
}
}
result
+=
car
.
getHasPowerWindows
()
?
100
:
0
;
result
+=
car
.
getHasPowerSteering
()
?
200
:
0
;
result
+=
car
.
getHasCruiseControl
()
?
400
:
0
;
result
+=
car
.
getHasNavSystem
()
?
2000
:
0
;
result
+=
car
.
getCupHolders
()
*
25
;
return
result
;
}
void
randomCar
(
Car
::
Builder
car
)
{
// Do not think too hard about realism.
static
const
char
*
const
MAKES
[]
=
{
"Toyota"
,
"GM"
,
"Ford"
,
"Honda"
,
"Tesla"
};
static
const
char
*
const
MODELS
[]
=
{
"Camry"
,
"Prius"
,
"Volt"
,
"Accord"
,
"Leaf"
,
"Model S"
};
car
.
setMake
(
MAKES
[
fastRand
(
sizeof
(
MAKES
)
/
sizeof
(
MAKES
[
0
]))]);
car
.
setModel
(
MODELS
[
fastRand
(
sizeof
(
MODELS
)
/
sizeof
(
MODELS
[
0
]))]);
// TODO: Color_RANGE or something.
car
.
setColor
((
Color
)
fastRand
((
uint
)
Color
::
SILVER
+
1
));
car
.
setSeats
(
2
+
fastRand
(
6
));
car
.
setDoors
(
2
+
fastRand
(
3
));
for
(
auto
wheel
:
car
.
initWheels
(
4
))
{
wheel
.
setDiameter
(
25
+
fastRand
(
15
));
wheel
.
setAirPressure
(
30
+
fastRandDouble
(
20
));
wheel
.
setSnowTires
(
fastRand
(
16
)
==
0
);
}
car
.
setLength
(
170
+
fastRand
(
150
));
car
.
setWidth
(
48
+
fastRand
(
36
));
car
.
setHeight
(
54
+
fastRand
(
48
));
car
.
setWeight
(
car
.
getLength
()
*
car
.
getWidth
()
*
car
.
getHeight
()
/
200
);
auto
engine
=
car
.
initEngine
();
engine
.
setHorsepower
(
100
*
fastRand
(
400
));
engine
.
setCylinders
(
4
+
2
*
fastRand
(
3
));
engine
.
setCc
(
800
+
fastRand
(
10000
));
car
.
setFuelCapacity
(
10.0
+
fastRandDouble
(
30.0
));
car
.
setFuelLevel
(
fastRandDouble
(
car
.
getFuelCapacity
()));
car
.
setHasPowerWindows
(
fastRand
(
2
));
car
.
setHasPowerSteering
(
fastRand
(
2
));
car
.
setHasCruiseControl
(
fastRand
(
2
));
car
.
setCupHolders
(
fastRand
(
12
));
car
.
setHasNavSystem
(
fastRand
(
2
));
}
class
CarSalesTestCase
{
public
:
typedef
ParkingLot
Request
;
typedef
TotalValue
Response
;
typedef
uint64_t
Expectation
;
static
uint64_t
setupRequest
(
ParkingLot
::
Builder
request
)
{
uint64_t
result
=
0
;
for
(
auto
car
:
request
.
initCars
(
fastRand
(
200
)))
{
randomCar
(
car
);
result
+=
carValue
(
car
);
}
return
result
;
}
static
void
handleRequest
(
ParkingLot
::
Reader
request
,
TotalValue
::
Builder
response
)
{
uint64_t
result
=
0
;
for
(
auto
car
:
request
.
getCars
())
{
result
+=
carValue
(
car
);
}
response
.
setAmount
(
result
);
}
static
inline
bool
checkResponse
(
TotalValue
::
Reader
response
,
uint64_t
expected
)
{
return
response
.
getAmount
()
==
expected
;
}
};
}
// namespace capnp
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
capnp
::
BenchmarkTypes
,
capnproto
::
benchmark
::
capnp
::
CarSalesTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/capnproto-catrank.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "catrank.capnp.h"
#include "capnproto-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
capnp
{
struct
ScoredResult
{
double
score
;
SearchResult
::
Reader
result
;
ScoredResult
()
=
default
;
ScoredResult
(
double
score
,
SearchResult
::
Reader
result
)
:
score
(
score
),
result
(
result
)
{}
inline
bool
operator
<
(
const
ScoredResult
&
other
)
const
{
return
score
>
other
.
score
;
}
};
class
CatRankTestCase
{
public
:
typedef
SearchResultList
Request
;
typedef
SearchResultList
Response
;
typedef
int
Expectation
;
static
int
setupRequest
(
SearchResultList
::
Builder
request
)
{
int
count
=
fastRand
(
1000
);
int
goodCount
=
0
;
auto
list
=
request
.
initResults
(
count
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
{
SearchResult
::
Builder
result
=
list
[
i
];
result
.
setScore
(
1000
-
i
);
int
urlSize
=
fastRand
(
100
);
static
const
char
URL_PREFIX
[]
=
"http://example.com/"
;
auto
url
=
result
.
initUrl
(
urlSize
+
sizeof
(
URL_PREFIX
));
strcpy
(
url
.
data
(),
URL_PREFIX
);
char
*
pos
=
url
.
data
()
+
strlen
(
URL_PREFIX
);
for
(
int
j
=
0
;
j
<
urlSize
;
j
++
)
{
*
pos
++
=
'a'
+
fastRand
(
26
);
}
bool
isCat
=
fastRand
(
8
)
==
0
;
bool
isDog
=
fastRand
(
8
)
==
0
;
goodCount
+=
isCat
&&
!
isDog
;
static
std
::
string
snippet
;
snippet
.
clear
();
snippet
.
push_back
(
' '
);
int
prefix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
prefix
;
j
++
)
{
snippet
.
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
if
(
isCat
)
snippet
.
append
(
"cat "
);
if
(
isDog
)
snippet
.
append
(
"dog "
);
int
suffix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
suffix
;
j
++
)
{
snippet
.
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
result
.
setSnippet
(
snippet
);
}
return
goodCount
;
}
static
inline
void
handleRequest
(
SearchResultList
::
Reader
request
,
SearchResultList
::
Builder
response
)
{
std
::
vector
<
ScoredResult
>
scoredResults
;
for
(
auto
result
:
request
.
getResults
())
{
double
score
=
result
.
getScore
();
if
(
strstr
(
result
.
getSnippet
().
c_str
(),
" cat "
)
!=
nullptr
)
{
score
*=
10000
;
}
if
(
strstr
(
result
.
getSnippet
().
c_str
(),
" dog "
)
!=
nullptr
)
{
score
/=
10000
;
}
scoredResults
.
emplace_back
(
score
,
result
);
}
std
::
sort
(
scoredResults
.
begin
(),
scoredResults
.
end
());
auto
list
=
response
.
initResults
(
scoredResults
.
size
());
auto
iter
=
list
.
begin
();
for
(
auto
result
:
scoredResults
)
{
iter
->
setScore
(
result
.
score
);
iter
->
setUrl
(
result
.
result
.
getUrl
());
iter
->
setSnippet
(
result
.
result
.
getSnippet
());
++
iter
;
}
}
static
inline
bool
checkResponse
(
SearchResultList
::
Reader
response
,
int
expectedGoodCount
)
{
int
goodCount
=
0
;
for
(
auto
result
:
response
.
getResults
())
{
if
(
result
.
getScore
()
>
1001
)
{
++
goodCount
;
}
else
{
break
;
}
}
return
goodCount
==
expectedGoodCount
;
}
};
}
// namespace capnp
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
capnp
::
BenchmarkTypes
,
capnproto
::
benchmark
::
capnp
::
CatRankTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/
benchmark-capnproto.c++
→
c++/src/capnproto/benchmark/
capnproto-common.h
View file @
4a32903c
This diff is collapsed.
Click to expand it.
c++/src/capnproto/benchmark/capnproto-eval.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "eval.capnp.h"
#include "capnproto-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
capnp
{
int32_t
makeExpression
(
Expression
::
Builder
exp
,
uint
depth
)
{
// TODO: Operation_RANGE or something.
exp
.
setOp
((
Operation
)(
fastRand
((
int
)
Operation
::
MODULUS
+
1
)));
uint32_t
left
,
right
;
if
(
fastRand
(
8
)
<
depth
)
{
exp
.
setLeftIsValue
(
true
);
left
=
fastRand
(
128
)
+
1
;
exp
.
setLeftValue
(
left
);
}
else
{
left
=
makeExpression
(
exp
.
initLeftExpression
(),
depth
+
1
);
}
if
(
fastRand
(
8
)
<
depth
)
{
exp
.
setRightIsValue
(
true
);
right
=
fastRand
(
128
)
+
1
;
exp
.
setRightValue
(
right
);
}
else
{
right
=
makeExpression
(
exp
.
initRightExpression
(),
depth
+
1
);
}
switch
(
exp
.
getOp
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
int32_t
evaluateExpression
(
Expression
::
Reader
exp
)
{
int32_t
left
,
right
;
if
(
exp
.
getLeftIsValue
())
{
left
=
exp
.
getLeftValue
();
}
else
{
left
=
evaluateExpression
(
exp
.
getLeftExpression
());
}
if
(
exp
.
getRightIsValue
())
{
right
=
exp
.
getRightValue
();
}
else
{
right
=
evaluateExpression
(
exp
.
getRightExpression
());
}
switch
(
exp
.
getOp
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
class
ExpressionTestCase
{
public
:
~
ExpressionTestCase
()
{}
typedef
Expression
Request
;
typedef
EvaluationResult
Response
;
typedef
int32_t
Expectation
;
static
inline
int32_t
setupRequest
(
Expression
::
Builder
request
)
{
return
makeExpression
(
request
,
0
);
}
static
inline
void
handleRequest
(
Expression
::
Reader
request
,
EvaluationResult
::
Builder
response
)
{
response
.
setValue
(
evaluateExpression
(
request
));
}
static
inline
bool
checkResponse
(
EvaluationResult
::
Reader
response
,
int32_t
expected
)
{
return
response
.
getValue
()
==
expected
;
}
};
}
// namespace capnp
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
capnp
::
BenchmarkTypes
,
capnproto
::
benchmark
::
capnp
::
ExpressionTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/
benchmark
.capnp
→
c++/src/capnproto/benchmark/
carsales
.capnp
View file @
4a32903c
...
...
@@ -21,46 +21,6 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum Operation {
add = 0;
subtract = 1;
multiply = 2;
divide = 3;
modulus = 4;
}
struct Expression {
op@0: Operation;
# TODO: Use unions once fully-implemented.
leftIsValue@1: Bool;
leftValue@2: Int32;
leftExpression@3: Expression;
rightIsValue@4: Bool;
rightValue@5: Int32;
rightExpression@6: Expression;
}
struct EvaluationResult {
value@0: Int32;
}
# ========================================================================================
struct SearchResultList {
results@0: List(SearchResult);
}
struct SearchResult {
url@0: Text;
score@1: Float64;
snippet@2: Text;
}
# ========================================================================================
struct ParkingLot {
cars@0: List(Car);
}
...
...
c++/src/capnproto/benchmark/
benchmark
.proto
→
c++/src/capnproto/benchmark/
carsales
.proto
View file @
4a32903c
...
...
@@ -23,42 +23,6 @@
package
capnproto
.
benchmark.protobuf
;
enum
Operation
{
ADD
=
0
;
SUBTRACT
=
1
;
MULTIPLY
=
2
;
DIVIDE
=
3
;
MODULUS
=
4
;
}
message
Expression
{
required
Operation
op
=
1
;
optional
int32
left_value
=
2
;
optional
Expression
left_expression
=
3
;
optional
int32
right_value
=
4
;
optional
Expression
right_expression
=
5
;
}
message
EvaluationResult
{
required
sint32
value
=
1
;
}
// =======================================================================================
message
SearchResultList
{
repeated
SearchResult
result
=
1
;
}
message
SearchResult
{
optional
string
url
=
1
;
optional
double
score
=
2
;
optional
string
snippet
=
3
;
}
// =======================================================================================
message
ParkingLot
{
repeated
Car
car
=
1
;
}
...
...
c++/src/capnproto/benchmark/catrank.capnp
0 → 100644
View file @
4a32903c
# Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SearchResultList {
results@0: List(SearchResult);
}
struct SearchResult {
url@0: Text;
score@1: Float64;
snippet@2: Text;
}
c++/src/capnproto/benchmark/catrank.proto
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package
capnproto
.
benchmark.protobuf
;
message
SearchResultList
{
repeated
SearchResult
result
=
1
;
}
message
SearchResult
{
optional
string
url
=
1
;
optional
double
score
=
2
;
optional
string
snippet
=
3
;
}
c++/src/capnproto/benchmark/
benchmark-
common.h
→
c++/src/capnproto/benchmark/common.h
View file @
4a32903c
...
...
@@ -21,8 +21,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CAPNPROTO_BENCHMARK_
BENCHMARK_
COMMON_H_
#define CAPNPROTO_BENCHMARK_
BENCHMARK_
COMMON_H_
#ifndef CAPNPROTO_BENCHMARK_COMMON_H_
#define CAPNPROTO_BENCHMARK_COMMON_H_
#include <unistd.h>
#include <limits>
...
...
@@ -260,33 +260,16 @@ uint64_t doBenchmark3(const std::string& mode, const std::string& reuse,
}
}
template
<
typename
BenchmarkTypes
>
template
<
typename
BenchmarkTypes
,
typename
TestCase
>
int
benchmarkMain
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
6
)
{
fprintf
(
stderr
,
"USAGE: %s TEST_CASE MODE REUSE COMPRESSION ITERATION_COUNT
\n
"
,
argv
[
0
]);
return
1
;
}
uint64_t
iters
=
strtoull
(
argv
[
5
],
nullptr
,
0
);
uint64_t
throughput
;
std
::
string
testcase
=
argv
[
1
];
if
(
testcase
==
"eval"
)
{
throughput
=
doBenchmark3
<
BenchmarkTypes
,
typename
BenchmarkTypes
::
ExpressionTestCase
>
(
argv
[
2
],
argv
[
3
],
argv
[
4
],
iters
);
}
else
if
(
testcase
==
"catrank"
)
{
throughput
=
doBenchmark3
<
BenchmarkTypes
,
typename
BenchmarkTypes
::
CatRankTestCase
>
(
argv
[
2
],
argv
[
3
],
argv
[
4
],
iters
);
}
else
if
(
testcase
==
"carsales"
)
{
throughput
=
doBenchmark3
<
BenchmarkTypes
,
typename
BenchmarkTypes
::
CarSalesTestCase
>
(
argv
[
2
],
argv
[
3
],
argv
[
4
],
iters
);
}
else
{
fprintf
(
stderr
,
"Unknown test case: %s
\n
"
,
testcase
.
c_str
());
if
(
argc
!=
5
)
{
fprintf
(
stderr
,
"USAGE: %s MODE REUSE COMPRESSION ITERATION_COUNT
\n
"
,
argv
[
0
]);
return
1
;
}
fprintf
(
stdout
,
"%llu"
,
(
long
long
unsigned
int
)
throughput
);
uint64_t
iters
=
strtoull
(
argv
[
4
],
nullptr
,
0
);
uint64_t
throughput
=
doBenchmark3
<
BenchmarkTypes
,
TestCase
>
(
argv
[
1
],
argv
[
2
],
argv
[
3
],
iters
);
fprintf
(
stdout
,
"%llu
\n
"
,
(
long
long
unsigned
int
)
throughput
);
return
0
;
}
...
...
@@ -294,4 +277,4 @@ int benchmarkMain(int argc, char* argv[]) {
}
// namespace capnproto
}
// namespace benchmark
#endif // CAPNPROTO_BENCHMARK_
BENCHMARK_
COMMON_H_
#endif // CAPNPROTO_BENCHMARK_COMMON_H_
c++/src/capnproto/benchmark/eval.capnp
0 → 100644
View file @
4a32903c
# Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
enum Operation {
add = 0;
subtract = 1;
multiply = 2;
divide = 3;
modulus = 4;
}
struct Expression {
op@0: Operation;
# TODO: Use unions once fully-implemented.
leftIsValue@1: Bool;
leftValue@2: Int32;
leftExpression@3: Expression;
rightIsValue@4: Bool;
rightValue@5: Int32;
rightExpression@6: Expression;
}
struct EvaluationResult {
value@0: Int32;
}
c++/src/capnproto/benchmark/eval.proto
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package
capnproto
.
benchmark.protobuf
;
enum
Operation
{
ADD
=
0
;
SUBTRACT
=
1
;
MULTIPLY
=
2
;
DIVIDE
=
3
;
MODULUS
=
4
;
}
message
Expression
{
required
Operation
op
=
1
;
optional
int32
left_value
=
2
;
optional
Expression
left_expression
=
3
;
optional
int32
right_value
=
4
;
optional
Expression
right_expression
=
5
;
}
message
EvaluationResult
{
required
sint32
value
=
1
;
}
c++/src/capnproto/benchmark/
benchmark-null
.c++
→
c++/src/capnproto/benchmark/
null-carsales
.c++
View file @
4a32903c
This diff is collapsed.
Click to expand it.
c++/src/capnproto/benchmark/null-catrank.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "null-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
null
{
struct
SearchResult
{
const
char
*
url
;
double
score
;
const
char
*
snippet
;
};
struct
ScoredResult
{
double
score
;
const
SearchResult
*
result
;
ScoredResult
()
=
default
;
ScoredResult
(
double
score
,
const
SearchResult
*
result
)
:
score
(
score
),
result
(
result
)
{}
inline
bool
operator
<
(
const
ScoredResult
&
other
)
const
{
return
score
>
other
.
score
;
}
};
class
CatRankTestCase
{
public
:
typedef
List
<
SearchResult
>
Request
;
typedef
List
<
SearchResult
>
Response
;
typedef
int
Expectation
;
static
int
setupRequest
(
List
<
SearchResult
>*
request
)
{
int
count
=
fastRand
(
1000
);
int
goodCount
=
0
;
request
->
init
(
count
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
{
SearchResult
&
result
=
request
->
items
[
i
];
result
.
score
=
1000
-
i
;
char
*
pos
=
reinterpret_cast
<
char
*>
(
arenaPos
);
result
.
url
=
pos
;
strcpy
(
pos
,
"http://example.com/"
);
pos
+=
strlen
(
"http://example.com/"
);
int
urlSize
=
fastRand
(
100
);
for
(
int
j
=
0
;
j
<
urlSize
;
j
++
)
{
*
pos
++
=
'a'
+
fastRand
(
26
);
}
*
pos
++
=
'\0'
;
// Retroactively allocate the space we used.
if
(
allocate
<
char
>
(
pos
-
result
.
url
)
!=
result
.
url
)
{
throw
std
::
bad_alloc
();
}
bool
isCat
=
fastRand
(
8
)
==
0
;
bool
isDog
=
fastRand
(
8
)
==
0
;
goodCount
+=
isCat
&&
!
isDog
;
pos
=
reinterpret_cast
<
char
*>
(
arenaPos
);
result
.
snippet
=
pos
;
*
pos
++
=
' '
;
int
prefix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
prefix
;
j
++
)
{
const
char
*
word
=
WORDS
[
fastRand
(
WORDS_COUNT
)];
size_t
len
=
strlen
(
word
);
memcpy
(
pos
,
word
,
len
);
pos
+=
len
;
}
if
(
isCat
)
{
strcpy
(
pos
,
"cat "
);
pos
+=
4
;
}
if
(
isDog
)
{
strcpy
(
pos
,
"dog "
);
pos
+=
4
;
}
int
suffix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
suffix
;
j
++
)
{
const
char
*
word
=
WORDS
[
fastRand
(
WORDS_COUNT
)];
size_t
len
=
strlen
(
word
);
memcpy
(
pos
,
word
,
len
);
pos
+=
len
;
}
*
pos
++
=
'\0'
;
// Retroactively allocate the space we used.
if
(
allocate
<
char
>
(
pos
-
result
.
snippet
)
!=
result
.
snippet
)
{
throw
std
::
bad_alloc
();
}
}
return
goodCount
;
}
static
inline
void
handleRequest
(
const
List
<
SearchResult
>&
request
,
List
<
SearchResult
>*
response
)
{
std
::
vector
<
ScoredResult
>
scoredResults
;
scoredResults
.
reserve
(
request
.
size
);
for
(
auto
&
result
:
request
)
{
double
score
=
result
.
score
;
if
(
strstr
(
result
.
snippet
,
" cat "
)
!=
nullptr
)
{
score
*=
10000
;
}
if
(
strstr
(
result
.
snippet
,
" dog "
)
!=
nullptr
)
{
score
/=
10000
;
}
scoredResults
.
emplace_back
(
score
,
&
result
);
}
std
::
sort
(
scoredResults
.
begin
(),
scoredResults
.
end
());
response
->
init
(
scoredResults
.
size
());
SearchResult
*
dst
=
response
->
items
;
for
(
auto
&
result
:
scoredResults
)
{
dst
->
url
=
copyString
(
result
.
result
->
url
);
dst
->
score
=
result
.
score
;
dst
->
snippet
=
copyString
(
result
.
result
->
snippet
);
++
dst
;
}
}
static
inline
bool
checkResponse
(
const
List
<
SearchResult
>&
response
,
int
expectedGoodCount
)
{
int
goodCount
=
0
;
for
(
auto
&
result
:
response
)
{
if
(
result
.
score
>
1001
)
{
++
goodCount
;
}
else
{
break
;
}
}
return
goodCount
==
expectedGoodCount
;
}
};
}
// namespace null
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
null
::
BenchmarkTypes
,
capnproto
::
benchmark
::
null
::
CatRankTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/null-common.h
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
null
{
uint64_t
arena
[
1024
*
1024
];
uint64_t
*
arenaPos
=
arena
;
template
<
typename
T
>
T
*
allocate
(
int
count
=
1
)
{
T
*
result
=
reinterpret_cast
<
T
*>
(
arenaPos
);
arenaPos
+=
(
sizeof
(
T
)
*
count
+
7
)
/
8
;
if
(
arenaPos
>
arena
+
sizeof
(
arena
)
/
sizeof
(
arena
[
0
]))
{
throw
std
::
bad_alloc
();
}
return
result
;
}
char
*
copyString
(
const
char
*
str
)
{
size_t
len
=
strlen
(
str
);
char
*
result
=
allocate
<
char
>
(
len
);
memcpy
(
result
,
str
,
len
+
1
);
return
result
;
}
template
<
typename
T
>
struct
List
{
size_t
size
;
T
*
items
;
inline
T
*
begin
()
const
{
return
items
;
}
inline
T
*
end
()
const
{
return
items
+
size
;
}
inline
List
<
T
>&
init
(
size_t
size
)
{
this
->
size
=
size
;
items
=
allocate
<
T
>
(
size
);
return
*
this
;
}
};
// =======================================================================================
struct
SingleUseObjects
{
template
<
typename
ObjectType
>
struct
Object
{
struct
Reusable
{};
struct
SingleUse
{
ObjectType
value
;
inline
SingleUse
(
Reusable
&
)
{}
};
};
};
struct
ReusableObjects
{
template
<
typename
ObjectType
>
struct
Object
{
typedef
ObjectType
Reusable
;
struct
SingleUse
{
ObjectType
&
value
;
inline
SingleUse
(
Reusable
&
reusable
)
:
value
(
reusable
)
{}
};
};
};
// =======================================================================================
template
<
typename
TestCase
,
typename
ReuseStrategy
,
typename
Compression
>
struct
BenchmarkMethods
{
static
uint64_t
syncClient
(
int
inputFd
,
int
outputFd
,
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
static
uint64_t
asyncClientSender
(
int
outputFd
,
ProducerConsumerQueue
<
typename
TestCase
::
Expectation
>*
expectations
,
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
static
void
asyncClientReceiver
(
int
inputFd
,
ProducerConsumerQueue
<
typename
TestCase
::
Expectation
>*
expectations
,
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
static
uint64_t
asyncClient
(
int
inputFd
,
int
outputFd
,
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
static
uint64_t
server
(
int
inputFd
,
int
outputFd
,
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
static
uint64_t
passByObject
(
uint64_t
iters
,
bool
countObjectSize
)
{
uint64_t
throughput
=
0
;
for
(;
iters
>
0
;
--
iters
)
{
arenaPos
=
arena
;
typename
TestCase
::
Request
request
;
typename
TestCase
::
Expectation
expected
=
TestCase
::
setupRequest
(
&
request
);
typename
TestCase
::
Response
response
;
TestCase
::
handleRequest
(
request
,
&
response
);
if
(
!
TestCase
::
checkResponse
(
response
,
expected
))
{
throw
std
::
logic_error
(
"Incorrect response."
);
}
throughput
+=
(
arenaPos
-
arena
)
*
sizeof
(
arena
[
0
]);
}
return
throughput
;
}
static
uint64_t
passByBytes
(
uint64_t
iters
)
{
fprintf
(
stderr
,
"Null benchmark doesn't do I/O.
\n
"
);
exit
(
1
);
}
};
struct
BenchmarkTypes
{
typedef
void
SnappyCompressed
;
typedef
void
Uncompressed
;
typedef
void
ReusableResources
;
typedef
void
SingleUseResources
;
template
<
typename
TestCase
,
typename
ReuseStrategy
,
typename
Compression
>
struct
BenchmarkMethods
:
public
null
::
BenchmarkMethods
<
TestCase
,
ReuseStrategy
,
Compression
>
{};
};
}
// namespace null
}
// namespace benchmark
}
// namespace capnproto
c++/src/capnproto/benchmark/null-eval.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "null-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
null
{
enum
class
Operation
{
ADD
,
SUBTRACT
,
MULTIPLY
,
DIVIDE
,
MODULUS
};
uint
OPERATION_RANGE
=
static_cast
<
uint
>
(
Operation
::
MODULUS
)
+
1
;
struct
Expression
{
Operation
op
;
bool
leftIsValue
;
bool
rightIsValue
;
union
{
int32_t
leftValue
;
Expression
*
leftExpression
;
};
union
{
int32_t
rightValue
;
Expression
*
rightExpression
;
};
};
int32_t
makeExpression
(
Expression
*
exp
,
uint
depth
)
{
exp
->
op
=
(
Operation
)(
fastRand
(
OPERATION_RANGE
));
int32_t
left
,
right
;
if
(
fastRand
(
8
)
<
depth
)
{
exp
->
leftIsValue
=
true
;
left
=
fastRand
(
128
)
+
1
;
exp
->
leftValue
=
left
;
}
else
{
exp
->
leftIsValue
=
false
;
exp
->
leftExpression
=
allocate
<
Expression
>
();
left
=
makeExpression
(
exp
->
leftExpression
,
depth
+
1
);
}
if
(
fastRand
(
8
)
<
depth
)
{
exp
->
rightIsValue
=
true
;
right
=
fastRand
(
128
)
+
1
;
exp
->
rightValue
=
right
;
}
else
{
exp
->
rightIsValue
=
false
;
exp
->
rightExpression
=
allocate
<
Expression
>
();
right
=
makeExpression
(
exp
->
rightExpression
,
depth
+
1
);
}
switch
(
exp
->
op
)
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
int32_t
evaluateExpression
(
const
Expression
&
exp
)
{
uint32_t
left
,
right
;
if
(
exp
.
leftIsValue
)
{
left
=
exp
.
leftValue
;
}
else
{
left
=
evaluateExpression
(
*
exp
.
leftExpression
);
}
if
(
exp
.
rightIsValue
)
{
right
=
exp
.
rightValue
;
}
else
{
right
=
evaluateExpression
(
*
exp
.
rightExpression
);
}
switch
(
exp
.
op
)
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
class
ExpressionTestCase
{
public
:
typedef
Expression
Request
;
typedef
int32_t
Response
;
typedef
int32_t
Expectation
;
static
inline
int32_t
setupRequest
(
Expression
*
request
)
{
return
makeExpression
(
request
,
0
);
}
static
inline
void
handleRequest
(
const
Expression
&
request
,
int32_t
*
response
)
{
*
response
=
evaluateExpression
(
request
);
}
static
inline
bool
checkResponse
(
int32_t
response
,
int32_t
expected
)
{
return
response
==
expected
;
}
static
size_t
spaceUsed
(
const
Expression
&
expression
)
{
return
sizeof
(
Expression
)
+
(
expression
.
leftExpression
==
nullptr
?
0
:
spaceUsed
(
*
expression
.
leftExpression
))
+
(
expression
.
rightExpression
==
nullptr
?
0
:
spaceUsed
(
*
expression
.
rightExpression
));
}
};
}
// namespace null
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
null
::
BenchmarkTypes
,
capnproto
::
benchmark
::
null
::
ExpressionTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/protobuf-carsales.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "carsales.pb.h"
#include "protobuf-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
protobuf
{
uint64_t
carValue
(
const
Car
&
car
)
{
// Do not think too hard about realism.
uint64_t
result
=
0
;
result
+=
car
.
seats
()
*
200
;
result
+=
car
.
doors
()
*
350
;
for
(
auto
&
wheel
:
car
.
wheel
())
{
result
+=
wheel
.
diameter
()
*
wheel
.
diameter
();
result
+=
wheel
.
snow_tires
()
?
100
:
0
;
}
result
+=
car
.
length
()
*
car
.
width
()
*
car
.
height
()
/
50
;
const
Engine
&
engine
=
car
.
engine
();
result
+=
engine
.
horsepower
()
*
40
;
if
(
engine
.
uses_electric
())
{
if
(
engine
.
uses_gas
())
{
// hybrid
result
+=
5000
;
}
else
{
result
+=
3000
;
}
}
result
+=
car
.
has_power_windows
()
?
100
:
0
;
result
+=
car
.
has_power_steering
()
?
200
:
0
;
result
+=
car
.
has_cruise_control
()
?
400
:
0
;
result
+=
car
.
has_nav_system
()
?
2000
:
0
;
result
+=
car
.
cup_holders
()
*
25
;
return
result
;
}
void
randomCar
(
Car
*
car
)
{
// Do not think too hard about realism.
static
const
char
*
const
MAKES
[]
=
{
"Toyota"
,
"GM"
,
"Ford"
,
"Honda"
,
"Tesla"
};
static
const
char
*
const
MODELS
[]
=
{
"Camry"
,
"Prius"
,
"Volt"
,
"Accord"
,
"Leaf"
,
"Model S"
};
car
->
set_make
(
MAKES
[
fastRand
(
sizeof
(
MAKES
)
/
sizeof
(
MAKES
[
0
]))]);
car
->
set_model
(
MODELS
[
fastRand
(
sizeof
(
MODELS
)
/
sizeof
(
MODELS
[
0
]))]);
car
->
set_color
((
Color
)
fastRand
(
Color_MAX
));
car
->
set_seats
(
2
+
fastRand
(
6
));
car
->
set_doors
(
2
+
fastRand
(
3
));
for
(
uint
i
=
0
;
i
<
4
;
i
++
)
{
Wheel
*
wheel
=
car
->
add_wheel
();
wheel
->
set_diameter
(
25
+
fastRand
(
15
));
wheel
->
set_air_pressure
(
30
+
fastRandDouble
(
20
));
wheel
->
set_snow_tires
(
fastRand
(
16
)
==
0
);
}
car
->
set_length
(
170
+
fastRand
(
150
));
car
->
set_width
(
48
+
fastRand
(
36
));
car
->
set_height
(
54
+
fastRand
(
48
));
car
->
set_weight
(
car
->
length
()
*
car
->
width
()
*
car
->
height
()
/
200
);
Engine
*
engine
=
car
->
mutable_engine
();
engine
->
set_horsepower
(
100
*
fastRand
(
400
));
engine
->
set_cylinders
(
4
+
2
*
fastRand
(
3
));
engine
->
set_cc
(
800
+
fastRand
(
10000
));
car
->
set_fuel_capacity
(
10.0
+
fastRandDouble
(
30.0
));
car
->
set_fuel_level
(
fastRandDouble
(
car
->
fuel_capacity
()));
car
->
set_has_power_windows
(
fastRand
(
2
));
car
->
set_has_power_steering
(
fastRand
(
2
));
car
->
set_has_cruise_control
(
fastRand
(
2
));
car
->
set_cup_holders
(
fastRand
(
12
));
car
->
set_has_nav_system
(
fastRand
(
2
));
}
class
CarSalesTestCase
{
public
:
typedef
ParkingLot
Request
;
typedef
TotalValue
Response
;
typedef
uint64_t
Expectation
;
static
uint64_t
setupRequest
(
ParkingLot
*
request
)
{
uint
count
=
fastRand
(
200
);
uint64_t
result
=
0
;
for
(
uint
i
=
0
;
i
<
count
;
i
++
)
{
Car
*
car
=
request
->
add_car
();
randomCar
(
car
);
result
+=
carValue
(
*
car
);
}
return
result
;
}
static
void
handleRequest
(
const
ParkingLot
&
request
,
TotalValue
*
response
)
{
uint64_t
result
=
0
;
for
(
auto
&
car
:
request
.
car
())
{
result
+=
carValue
(
car
);
}
response
->
set_amount
(
result
);
}
static
inline
bool
checkResponse
(
const
TotalValue
&
response
,
uint64_t
expected
)
{
return
response
.
amount
()
==
expected
;
}
};
}
// namespace protobuf
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
protobuf
::
BenchmarkTypes
,
capnproto
::
benchmark
::
protobuf
::
CarSalesTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/protobuf-catrank.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "catrank.pb.h"
#include "protobuf-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
protobuf
{
struct
ScoredResult
{
double
score
;
const
SearchResult
*
result
;
ScoredResult
()
=
default
;
ScoredResult
(
double
score
,
const
SearchResult
*
result
)
:
score
(
score
),
result
(
result
)
{}
inline
bool
operator
<
(
const
ScoredResult
&
other
)
const
{
return
score
>
other
.
score
;
}
};
class
CatRankTestCase
{
public
:
typedef
SearchResultList
Request
;
typedef
SearchResultList
Response
;
typedef
int
Expectation
;
static
int
setupRequest
(
SearchResultList
*
request
)
{
int
count
=
fastRand
(
1000
);
int
goodCount
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++
)
{
SearchResult
*
result
=
request
->
add_result
();
result
->
set_score
(
1000
-
i
);
result
->
set_url
(
"http://example.com/"
);
std
::
string
*
url
=
result
->
mutable_url
();
int
urlSize
=
fastRand
(
100
);
for
(
int
j
=
0
;
j
<
urlSize
;
j
++
)
{
url
->
push_back
(
'a'
+
fastRand
(
26
));
}
bool
isCat
=
fastRand
(
8
)
==
0
;
bool
isDog
=
fastRand
(
8
)
==
0
;
goodCount
+=
isCat
&&
!
isDog
;
std
::
string
*
snippet
=
result
->
mutable_snippet
();
snippet
->
push_back
(
' '
);
int
prefix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
prefix
;
j
++
)
{
snippet
->
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
if
(
isCat
)
snippet
->
append
(
"cat "
);
if
(
isDog
)
snippet
->
append
(
"dog "
);
int
suffix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
suffix
;
j
++
)
{
snippet
->
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
}
return
goodCount
;
}
static
inline
void
handleRequest
(
const
SearchResultList
&
request
,
SearchResultList
*
response
)
{
std
::
vector
<
ScoredResult
>
scoredResults
;
for
(
auto
&
result
:
request
.
result
())
{
double
score
=
result
.
score
();
if
(
result
.
snippet
().
find
(
" cat "
)
!=
std
::
string
::
npos
)
{
score
*=
10000
;
}
if
(
result
.
snippet
().
find
(
" dog "
)
!=
std
::
string
::
npos
)
{
score
/=
10000
;
}
scoredResults
.
emplace_back
(
score
,
&
result
);
}
std
::
sort
(
scoredResults
.
begin
(),
scoredResults
.
end
());
for
(
auto
&
result
:
scoredResults
)
{
SearchResult
*
out
=
response
->
add_result
();
out
->
set_score
(
result
.
score
);
out
->
set_url
(
result
.
result
->
url
());
out
->
set_snippet
(
result
.
result
->
snippet
());
}
}
static
inline
bool
checkResponse
(
const
SearchResultList
&
response
,
int
expectedGoodCount
)
{
int
goodCount
=
0
;
for
(
auto
&
result
:
response
.
result
())
{
if
(
result
.
score
()
>
1001
)
{
++
goodCount
;
}
else
{
break
;
}
}
return
goodCount
==
expectedGoodCount
;
}
};
}
// namespace protobuf
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
protobuf
::
BenchmarkTypes
,
capnproto
::
benchmark
::
protobuf
::
CatRankTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/
benchmark-protobuf.c++
→
c++/src/capnproto/benchmark/
protobuf-common.h
View file @
4a32903c
...
...
@@ -21,8 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "benchmark.pb.h"
#include "benchmark-common.h"
#include "common.h"
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <thread>
#include <snappy/snappy.h>
...
...
@@ -32,299 +31,6 @@ namespace capnproto {
namespace
benchmark
{
namespace
protobuf
{
// =======================================================================================
// Test case: Expression evaluation
int32_t
makeExpression
(
Expression
*
exp
,
uint
depth
)
{
exp
->
set_op
((
Operation
)(
fastRand
(
Operation_MAX
+
1
)));
int32_t
left
,
right
;
if
(
fastRand
(
8
)
<
depth
)
{
left
=
fastRand
(
128
)
+
1
;
exp
->
set_left_value
(
left
);
}
else
{
left
=
makeExpression
(
exp
->
mutable_left_expression
(),
depth
+
1
);
}
if
(
fastRand
(
8
)
<
depth
)
{
right
=
fastRand
(
128
)
+
1
;
exp
->
set_right_value
(
right
);
}
else
{
right
=
makeExpression
(
exp
->
mutable_right_expression
(),
depth
+
1
);
}
switch
(
exp
->
op
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
int32_t
evaluateExpression
(
const
Expression
&
exp
)
{
uint32_t
left
,
right
;
if
(
exp
.
has_left_value
())
{
left
=
exp
.
left_value
();
}
else
{
left
=
evaluateExpression
(
exp
.
left_expression
());
}
if
(
exp
.
has_right_value
())
{
right
=
exp
.
right_value
();
}
else
{
right
=
evaluateExpression
(
exp
.
right_expression
());
}
switch
(
exp
.
op
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
class
ExpressionTestCase
{
public
:
typedef
Expression
Request
;
typedef
EvaluationResult
Response
;
typedef
int32_t
Expectation
;
static
inline
int32_t
setupRequest
(
Expression
*
request
)
{
return
makeExpression
(
request
,
0
);
}
static
inline
void
handleRequest
(
const
Expression
&
request
,
EvaluationResult
*
response
)
{
response
->
set_value
(
evaluateExpression
(
request
));
}
static
inline
bool
checkResponse
(
const
EvaluationResult
&
response
,
int32_t
expected
)
{
return
response
.
value
()
==
expected
;
}
};
// =======================================================================================
// Test case: Cat Rank
//
// The server receives a list of candidate search results with scores. It promotes the ones that
// mention "cat" in their snippet and demotes the ones that mention "dog", sorts the results by
// descending score, and returns.
//
// The promotion multiplier is large enough that all the results mentioning "cat" but not "dog"
// should end up at the front ofthe list, which is how we verify the result.
struct
ScoredResult
{
double
score
;
const
SearchResult
*
result
;
ScoredResult
()
=
default
;
ScoredResult
(
double
score
,
const
SearchResult
*
result
)
:
score
(
score
),
result
(
result
)
{}
inline
bool
operator
<
(
const
ScoredResult
&
other
)
const
{
return
score
>
other
.
score
;
}
};
class
CatRankTestCase
{
public
:
typedef
SearchResultList
Request
;
typedef
SearchResultList
Response
;
typedef
int
Expectation
;
static
int
setupRequest
(
SearchResultList
*
request
)
{
int
count
=
fastRand
(
1000
);
int
goodCount
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++
)
{
SearchResult
*
result
=
request
->
add_result
();
result
->
set_score
(
1000
-
i
);
result
->
set_url
(
"http://example.com/"
);
std
::
string
*
url
=
result
->
mutable_url
();
int
urlSize
=
fastRand
(
100
);
for
(
int
j
=
0
;
j
<
urlSize
;
j
++
)
{
url
->
push_back
(
'a'
+
fastRand
(
26
));
}
bool
isCat
=
fastRand
(
8
)
==
0
;
bool
isDog
=
fastRand
(
8
)
==
0
;
goodCount
+=
isCat
&&
!
isDog
;
std
::
string
*
snippet
=
result
->
mutable_snippet
();
snippet
->
push_back
(
' '
);
int
prefix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
prefix
;
j
++
)
{
snippet
->
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
if
(
isCat
)
snippet
->
append
(
"cat "
);
if
(
isDog
)
snippet
->
append
(
"dog "
);
int
suffix
=
fastRand
(
20
);
for
(
int
j
=
0
;
j
<
suffix
;
j
++
)
{
snippet
->
append
(
WORDS
[
fastRand
(
WORDS_COUNT
)]);
}
}
return
goodCount
;
}
static
inline
void
handleRequest
(
const
SearchResultList
&
request
,
SearchResultList
*
response
)
{
std
::
vector
<
ScoredResult
>
scoredResults
;
for
(
auto
&
result
:
request
.
result
())
{
double
score
=
result
.
score
();
if
(
result
.
snippet
().
find
(
" cat "
)
!=
std
::
string
::
npos
)
{
score
*=
10000
;
}
if
(
result
.
snippet
().
find
(
" dog "
)
!=
std
::
string
::
npos
)
{
score
/=
10000
;
}
scoredResults
.
emplace_back
(
score
,
&
result
);
}
std
::
sort
(
scoredResults
.
begin
(),
scoredResults
.
end
());
for
(
auto
&
result
:
scoredResults
)
{
SearchResult
*
out
=
response
->
add_result
();
out
->
set_score
(
result
.
score
);
out
->
set_url
(
result
.
result
->
url
());
out
->
set_snippet
(
result
.
result
->
snippet
());
}
}
static
inline
bool
checkResponse
(
const
SearchResultList
&
response
,
int
expectedGoodCount
)
{
int
goodCount
=
0
;
for
(
auto
&
result
:
response
.
result
())
{
if
(
result
.
score
()
>
1001
)
{
++
goodCount
;
}
else
{
break
;
}
}
return
goodCount
==
expectedGoodCount
;
}
};
// =======================================================================================
// Test case: Car Sales
//
// We have a parking lot full of cars and we want to know how much they are worth.
uint64_t
carValue
(
const
Car
&
car
)
{
// Do not think too hard about realism.
uint64_t
result
=
0
;
result
+=
car
.
seats
()
*
200
;
result
+=
car
.
doors
()
*
350
;
for
(
auto
&
wheel
:
car
.
wheel
())
{
result
+=
wheel
.
diameter
()
*
wheel
.
diameter
();
result
+=
wheel
.
snow_tires
()
?
100
:
0
;
}
result
+=
car
.
length
()
*
car
.
width
()
*
car
.
height
()
/
50
;
const
Engine
&
engine
=
car
.
engine
();
result
+=
engine
.
horsepower
()
*
40
;
if
(
engine
.
uses_electric
())
{
if
(
engine
.
uses_gas
())
{
// hybrid
result
+=
5000
;
}
else
{
result
+=
3000
;
}
}
result
+=
car
.
has_power_windows
()
?
100
:
0
;
result
+=
car
.
has_power_steering
()
?
200
:
0
;
result
+=
car
.
has_cruise_control
()
?
400
:
0
;
result
+=
car
.
has_nav_system
()
?
2000
:
0
;
result
+=
car
.
cup_holders
()
*
25
;
return
result
;
}
void
randomCar
(
Car
*
car
)
{
// Do not think too hard about realism.
static
const
char
*
const
MAKES
[]
=
{
"Toyota"
,
"GM"
,
"Ford"
,
"Honda"
,
"Tesla"
};
static
const
char
*
const
MODELS
[]
=
{
"Camry"
,
"Prius"
,
"Volt"
,
"Accord"
,
"Leaf"
,
"Model S"
};
car
->
set_make
(
MAKES
[
fastRand
(
sizeof
(
MAKES
)
/
sizeof
(
MAKES
[
0
]))]);
car
->
set_model
(
MODELS
[
fastRand
(
sizeof
(
MODELS
)
/
sizeof
(
MODELS
[
0
]))]);
car
->
set_color
((
Color
)
fastRand
(
Color_MAX
));
car
->
set_seats
(
2
+
fastRand
(
6
));
car
->
set_doors
(
2
+
fastRand
(
3
));
for
(
uint
i
=
0
;
i
<
4
;
i
++
)
{
Wheel
*
wheel
=
car
->
add_wheel
();
wheel
->
set_diameter
(
25
+
fastRand
(
15
));
wheel
->
set_air_pressure
(
30
+
fastRandDouble
(
20
));
wheel
->
set_snow_tires
(
fastRand
(
16
)
==
0
);
}
car
->
set_length
(
170
+
fastRand
(
150
));
car
->
set_width
(
48
+
fastRand
(
36
));
car
->
set_height
(
54
+
fastRand
(
48
));
car
->
set_weight
(
car
->
length
()
*
car
->
width
()
*
car
->
height
()
/
200
);
Engine
*
engine
=
car
->
mutable_engine
();
engine
->
set_horsepower
(
100
*
fastRand
(
400
));
engine
->
set_cylinders
(
4
+
2
*
fastRand
(
3
));
engine
->
set_cc
(
800
+
fastRand
(
10000
));
car
->
set_fuel_capacity
(
10.0
+
fastRandDouble
(
30.0
));
car
->
set_fuel_level
(
fastRandDouble
(
car
->
fuel_capacity
()));
car
->
set_has_power_windows
(
fastRand
(
2
));
car
->
set_has_power_steering
(
fastRand
(
2
));
car
->
set_has_cruise_control
(
fastRand
(
2
));
car
->
set_cup_holders
(
fastRand
(
12
));
car
->
set_has_nav_system
(
fastRand
(
2
));
}
class
CarSalesTestCase
{
public
:
typedef
ParkingLot
Request
;
typedef
TotalValue
Response
;
typedef
uint64_t
Expectation
;
static
uint64_t
setupRequest
(
ParkingLot
*
request
)
{
uint
count
=
fastRand
(
200
);
uint64_t
result
=
0
;
for
(
uint
i
=
0
;
i
<
count
;
i
++
)
{
Car
*
car
=
request
->
add_car
();
randomCar
(
car
);
result
+=
carValue
(
*
car
);
}
return
result
;
}
static
void
handleRequest
(
const
ParkingLot
&
request
,
TotalValue
*
response
)
{
uint64_t
result
=
0
;
for
(
auto
&
car
:
request
.
car
())
{
result
+=
carValue
(
car
);
}
response
->
set_amount
(
result
);
}
static
inline
bool
checkResponse
(
const
TotalValue
&
response
,
uint64_t
expected
)
{
return
response
.
amount
()
==
expected
;
}
};
// =======================================================================================
struct
SingleUseMessages
{
...
...
@@ -629,10 +335,6 @@ struct BenchmarkMethods {
};
struct
BenchmarkTypes
{
typedef
protobuf
::
ExpressionTestCase
ExpressionTestCase
;
typedef
protobuf
::
CatRankTestCase
CatRankTestCase
;
typedef
protobuf
::
CarSalesTestCase
CarSalesTestCase
;
typedef
protobuf
::
SnappyCompressed
SnappyCompressed
;
typedef
protobuf
::
Uncompressed
Uncompressed
;
...
...
@@ -647,8 +349,3 @@ struct BenchmarkTypes {
}
// namespace protobuf
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
protobuf
::
BenchmarkTypes
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/protobuf-eval.c++
0 → 100644
View file @
4a32903c
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "eval.pb.h"
#include "protobuf-common.h"
namespace
capnproto
{
namespace
benchmark
{
namespace
protobuf
{
int32_t
makeExpression
(
Expression
*
exp
,
uint
depth
)
{
exp
->
set_op
((
Operation
)(
fastRand
(
Operation_MAX
+
1
)));
int32_t
left
,
right
;
if
(
fastRand
(
8
)
<
depth
)
{
left
=
fastRand
(
128
)
+
1
;
exp
->
set_left_value
(
left
);
}
else
{
left
=
makeExpression
(
exp
->
mutable_left_expression
(),
depth
+
1
);
}
if
(
fastRand
(
8
)
<
depth
)
{
right
=
fastRand
(
128
)
+
1
;
exp
->
set_right_value
(
right
);
}
else
{
right
=
makeExpression
(
exp
->
mutable_right_expression
(),
depth
+
1
);
}
switch
(
exp
->
op
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
int32_t
evaluateExpression
(
const
Expression
&
exp
)
{
uint32_t
left
,
right
;
if
(
exp
.
has_left_value
())
{
left
=
exp
.
left_value
();
}
else
{
left
=
evaluateExpression
(
exp
.
left_expression
());
}
if
(
exp
.
has_right_value
())
{
right
=
exp
.
right_value
();
}
else
{
right
=
evaluateExpression
(
exp
.
right_expression
());
}
switch
(
exp
.
op
())
{
case
Operation
:
:
ADD
:
return
left
+
right
;
case
Operation
:
:
SUBTRACT
:
return
left
-
right
;
case
Operation
:
:
MULTIPLY
:
return
left
*
right
;
case
Operation
:
:
DIVIDE
:
return
div
(
left
,
right
);
case
Operation
:
:
MODULUS
:
return
mod
(
left
,
right
);
}
throw
std
::
logic_error
(
"Can't get here."
);
}
class
ExpressionTestCase
{
public
:
typedef
Expression
Request
;
typedef
EvaluationResult
Response
;
typedef
int32_t
Expectation
;
static
inline
int32_t
setupRequest
(
Expression
*
request
)
{
return
makeExpression
(
request
,
0
);
}
static
inline
void
handleRequest
(
const
Expression
&
request
,
EvaluationResult
*
response
)
{
response
->
set_value
(
evaluateExpression
(
request
));
}
static
inline
bool
checkResponse
(
const
EvaluationResult
&
response
,
int32_t
expected
)
{
return
response
.
value
()
==
expected
;
}
};
}
// namespace protobuf
}
// namespace benchmark
}
// namespace capnproto
int
main
(
int
argc
,
char
*
argv
[])
{
return
capnproto
::
benchmark
::
benchmarkMain
<
capnproto
::
benchmark
::
protobuf
::
BenchmarkTypes
,
capnproto
::
benchmark
::
protobuf
::
ExpressionTestCase
>
(
argc
,
argv
);
}
c++/src/capnproto/benchmark/
benchmark-
runner.c++
→
c++/src/capnproto/benchmark/runner.c++
View file @
4a32903c
...
...
@@ -94,6 +94,19 @@ enum class TestCase {
CARSALES
};
const
char
*
testCaseName
(
TestCase
testCase
)
{
switch
(
testCase
)
{
case
TestCase
:
:
EVAL
:
return
"eval"
;
case
TestCase
:
:
CATRANK
:
return
"catrank"
;
case
TestCase
:
:
CARSALES
:
return
"carsales"
;
}
// Can't get here.
return
nullptr
;
}
enum
class
Mode
{
OBJECTS
,
OBJECT_SIZE
,
...
...
@@ -114,73 +127,66 @@ enum class Compression {
TestResult
runTest
(
Product
product
,
TestCase
testCase
,
Mode
mode
,
Reuse
reuse
,
Compression
compression
,
uint64_t
iters
)
{
char
*
argv
[
7
];
char
*
argv
[
6
];
string
progName
;
switch
(
product
)
{
case
Product
:
:
CAPNPROTO
:
argv
[
0
]
=
strdup
(
"benchmark-capnproto"
)
;
progName
=
"capnproto-"
;
break
;
case
Product
:
:
PROTOBUF
:
argv
[
0
]
=
strdup
(
"benchmark-protobuf"
)
;
progName
=
"protobuf-"
;
break
;
case
Product
:
:
NULLCASE
:
argv
[
0
]
=
strdup
(
"benchmark-null"
)
;
progName
=
"null-"
;
break
;
}
switch
(
testCase
)
{
case
TestCase
:
:
EVAL
:
argv
[
1
]
=
strdup
(
"eval"
);
break
;
case
TestCase
:
:
CATRANK
:
argv
[
1
]
=
strdup
(
"catrank"
);
break
;
case
TestCase
:
:
CARSALES
:
argv
[
1
]
=
strdup
(
"carsales"
);
break
;
}
progName
+=
testCaseName
(
testCase
);
argv
[
0
]
=
progName
.
c_str
();
switch
(
mode
)
{
case
Mode
:
:
OBJECTS
:
argv
[
2
]
=
strdup
(
"object"
);
argv
[
1
]
=
strdup
(
"object"
);
break
;
case
Mode
:
:
OBJECT_SIZE
:
argv
[
2
]
=
strdup
(
"object-size"
);
argv
[
1
]
=
strdup
(
"object-size"
);
break
;
case
Mode
:
:
BYTES
:
argv
[
2
]
=
strdup
(
"bytes"
);
argv
[
1
]
=
strdup
(
"bytes"
);
break
;
case
Mode
:
:
PIPE_SYNC
:
argv
[
2
]
=
strdup
(
"pipe"
);
argv
[
1
]
=
strdup
(
"pipe"
);
break
;
case
Mode
:
:
PIPE_ASYNC
:
argv
[
2
]
=
strdup
(
"pipe-async"
);
argv
[
1
]
=
strdup
(
"pipe-async"
);
break
;
}
switch
(
reuse
)
{
case
Reuse
:
:
YES
:
argv
[
3
]
=
strdup
(
"reuse"
);
argv
[
2
]
=
strdup
(
"reuse"
);
break
;
case
Reuse
:
:
NO
:
argv
[
3
]
=
strdup
(
"no-reuse"
);
argv
[
2
]
=
strdup
(
"no-reuse"
);
break
;
}
switch
(
compression
)
{
case
Compression
:
:
SNAPPY
:
argv
[
4
]
=
strdup
(
"snappy"
);
argv
[
3
]
=
strdup
(
"snappy"
);
break
;
case
Compression
:
:
NONE
:
argv
[
4
]
=
strdup
(
"none"
);
argv
[
3
]
=
strdup
(
"none"
);
break
;
}
char
itersStr
[
64
];
sprintf
(
itersStr
,
"%llu"
,
(
long
long
unsigned
int
)
iters
);
argv
[
5
]
=
itersStr
;
argv
[
4
]
=
itersStr
;
argv
[
6
]
=
nullptr
;
argv
[
5
]
=
nullptr
;
// Make pipe for child to write throughput.
int
childPipe
[
2
];
...
...
@@ -202,7 +208,7 @@ TestResult runTest(Product product, TestCase testCase, Mode mode, Reuse reuse,
}
close
(
childPipe
[
1
]);
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
for
(
int
i
=
1
;
i
<
4
;
i
++
)
{
free
(
argv
[
i
]);
}
...
...
@@ -308,10 +314,10 @@ void reportComparison(const char* name, const char* unit, double protobuf, doubl
cout
<<
setw
(
14
)
<<
right
<<
Gain
(
capnproto
,
protobuf
)
<<
endl
;
}
size_t
fileSize
(
const
char
*
name
)
{
size_t
fileSize
(
const
std
::
string
&
name
)
{
struct
stat
stats
;
if
(
stat
(
name
,
&
stats
)
<
0
)
{
perror
(
name
);
if
(
stat
(
name
.
c_str
()
,
&
stats
)
<
0
)
{
perror
(
name
.
c_str
()
);
exit
(
1
);
}
...
...
@@ -454,12 +460,16 @@ int main(int argc, char* argv[]) {
(
capnp
.
time
.
cpu
()
-
capnpBase
.
time
.
cpu
())
/
1000.0
,
iters
);
reportComparison
(
"binary size"
,
"kB"
,
fileSize
(
"benchmark-protobuf"
)
/
1024.0
,
fileSize
(
"benchmark-capnproto"
)
/
1024.0
,
1
);
fileSize
(
"protobuf-"
+
std
::
string
(
testCaseName
(
testCase
)))
/
1024.0
,
fileSize
(
"capnproto-"
+
std
::
string
(
testCaseName
(
testCase
)))
/
1024.0
,
1
);
reportComparison
(
"generated code size"
,
"kB"
,
fileSize
(
"benchmark.pb.cc"
)
/
1024.0
+
fileSize
(
"benchmark.pb.h"
)
/
1024.0
,
fileSize
(
"benchmark.capnp.c++"
)
/
1024.0
+
fileSize
(
"benchmark.capnp.h"
)
/
1024.0
,
1
);
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".pb.cc"
)
/
1024.0
+
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".pb.h"
)
/
1024.0
,
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".capnp.c++"
)
/
1024.0
+
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".capnp.h"
)
/
1024.0
,
1
);
reportComparison
(
"generated obj size"
,
"kB"
,
fileSize
(
"benchmark.pb.o"
)
/
1024.0
,
fileSize
(
"benchmark.capnp.o"
)
/
1024.0
,
1
);
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".pb.o"
)
/
1024.0
,
fileSize
(
std
::
string
(
testCaseName
(
testCase
))
+
".capnp.o"
)
/
1024.0
,
1
);
return
0
;
}
...
...
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