Add benchmarks
This commit is contained in:
120
benchmark/eval_pycapnp.py
Executable file
120
benchmark/eval_pycapnp.py
Executable file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import capnp
|
||||
import eval_capnp
|
||||
from common import rand_int, rand_double, rand_bool
|
||||
from random import choice
|
||||
|
||||
MAX_INT = 2**31 - 1
|
||||
MIN_INT = -(2**31)
|
||||
|
||||
OPERATIONS = [
|
||||
"add",
|
||||
"subtract",
|
||||
"multiply",
|
||||
"divide",
|
||||
"modulus"]
|
||||
|
||||
def clamp(res):
|
||||
if res > MAX_INT:
|
||||
return MAX_INT
|
||||
elif res < MIN_INT:
|
||||
return MIN_INT
|
||||
else:
|
||||
return res
|
||||
|
||||
def div(a, b):
|
||||
if b == 0:
|
||||
return MAX_INT
|
||||
if a == MIN_INT and b == -1:
|
||||
return MAX_INT
|
||||
|
||||
return a / b
|
||||
|
||||
def mod(a, b):
|
||||
if b == 0:
|
||||
return MAX_INT
|
||||
if a == MIN_INT and b == -1:
|
||||
return MAX_INT
|
||||
|
||||
return a % b
|
||||
|
||||
def make_expression(exp, depth):
|
||||
exp.op = choice(OPERATIONS)
|
||||
|
||||
if rand_int(8) < depth:
|
||||
left = rand_int(128) + 1
|
||||
exp.left.value = left
|
||||
else:
|
||||
left = make_expression(exp.left.init('expression'), depth+1)
|
||||
|
||||
if rand_int(8) < depth:
|
||||
right = rand_int(128) + 1
|
||||
exp.right.value = right
|
||||
else:
|
||||
right = make_expression(exp.right.init('expression'), depth+1)
|
||||
|
||||
op = exp.op
|
||||
if op == 'add':
|
||||
return clamp(left + right)
|
||||
elif op == 'subtract':
|
||||
return clamp(left - right)
|
||||
elif op == 'multiply':
|
||||
return clamp(left * right)
|
||||
elif op == 'divide':
|
||||
return div(left, right)
|
||||
elif op == 'modulus':
|
||||
return mod(left, right)
|
||||
raise RuntimeError("op wasn't a valid value: " + str(op))
|
||||
|
||||
def evaluate_expression(exp):
|
||||
left = 0
|
||||
right = 0
|
||||
|
||||
which = exp.left.which()
|
||||
if which == 'value':
|
||||
left = exp.left.value
|
||||
elif which == 'expression':
|
||||
left = evaluate_expression(exp.left.expression)
|
||||
|
||||
which = exp.right.which()
|
||||
if which == 'value':
|
||||
right = exp.right.value
|
||||
elif which == 'expression':
|
||||
right = evaluate_expression(exp.right.expression)
|
||||
|
||||
|
||||
op = exp.op
|
||||
if op == 'add':
|
||||
return clamp(left + right)
|
||||
elif op == 'subtract':
|
||||
return clamp(left - right)
|
||||
elif op == 'multiply':
|
||||
return clamp(left * right)
|
||||
elif op == 'divide':
|
||||
return div(left, right)
|
||||
elif op == 'modulus':
|
||||
return mod(left, right)
|
||||
raise RuntimeError("op wasn't a valid value: " + str(op))
|
||||
|
||||
class Benchmark:
|
||||
def __init__(self, compression):
|
||||
self.Request = eval_capnp.Expression.new_message
|
||||
self.Response = eval_capnp.EvaluationResult.new_message
|
||||
if compression == 'packed':
|
||||
self.from_bytes_request = eval_capnp.Expression.from_bytes_packed
|
||||
self.from_bytes_response = eval_capnp.EvaluationResult.from_bytes_packed
|
||||
self.to_bytes = lambda x: x.to_bytes_packed()
|
||||
else:
|
||||
self.from_bytes_request = eval_capnp.Expression.from_bytes
|
||||
self.from_bytes_response = eval_capnp.EvaluationResult.from_bytes
|
||||
self.to_bytes = lambda x: x.to_bytes()
|
||||
|
||||
def setup(self, request):
|
||||
return make_expression(request, 0)
|
||||
|
||||
def handle(self, request, response):
|
||||
response.value = evaluate_expression(request)
|
||||
|
||||
def check(self, response, expected):
|
||||
return response.value == expected
|
||||
Reference in New Issue
Block a user