Add benchmark suite

This commit is contained in:
K. Lange 2021-04-14 22:25:22 +09:00
parent 37c3101578
commit 5f766a5726
9 changed files with 332 additions and 1 deletions

View File

@ -139,7 +139,7 @@ libtcmalloc_minimal.a:
# Test targets run against all .krk files in the test/ directory, writing
# stdout to `.expect` files, and then comparing with `git`.
# To update the tests if changes are expected, run `make test` and commit the result.
.PHONY: test stress-test update-tests
.PHONY: test stress-test update-tests bench
test:
@for i in test/*.krk; do echo $$i; KUROKO_TEST_ENV=1 $(TESTWRAPPER) ./kuroko $$i > $$i.actual; diff $$i.expect $$i.actual || exit 1; rm $$i.actual; done
@ -150,6 +150,12 @@ update-tests:
stress-test:
$(MAKE) TESTWRAPPER='valgrind' test
bench:
@echo "Kuroko:"
@for i in bench/*.krk; do ./kuroko "$$i"; done
@echo "CPython:"
@for i in bench/*.py; do python3 "$$i"; done
# Really should be up to you to set, not us...
multiarch ?= $(shell gcc -print-multiarch)
prefix ?= /usr/local

126
bench/bench.krk Normal file
View File

@ -0,0 +1,126 @@
# Show relative speeds of local, nonlocal, global, and built-in access.
class _A(object):
def m(self):
pass
let v_global = 1
def read_local():
let v_local = 1
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
def make_nonlocal_reader():
let v_nonlocal = 1
def inner():
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
return inner
let read_nonlocal = make_nonlocal_reader()
def read_global():
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
def read_builtin():
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
def read_classvar():
let A = _A
A.x = 1
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
def read_instancevar():
let a = _A()
a.x = 1
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
def read_unboundmethod():
let A = _A
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
def read_boundmethod():
let a = _A()
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
def write_local():
let v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
def make_nonlocal_writer():
let v_nonlocal = 1
def inner():
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
return inner
let write_nonlocal = make_nonlocal_writer()
def write_global():
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
def write_classvar():
let A = _A
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
def write_instancevar():
let a = _A()
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
if __name__=='__main__':
from timeit import timeit
for f in [read_local, read_nonlocal, read_global, read_builtin,
read_classvar, read_instancevar, read_unboundmethod, read_boundmethod,
write_local, write_nonlocal, write_global,
write_classvar, write_instancevar]:
print(timeit(f,number=1000000), f.__qualname__)

129
bench/bench.py Normal file
View File

@ -0,0 +1,129 @@
# Show relative speeds of local, nonlocal, global, and built-in access.
class _A(object):
def m(self):
pass
v_global = 1
def read_local():
v_local = 1
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
v_local; v_local; v_local; v_local; v_local
def make_nonlocal_reader():
v_nonlocal = 1
def inner():
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal; v_nonlocal
return inner
read_nonlocal = make_nonlocal_reader()
def read_global():
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
v_global; v_global; v_global; v_global; v_global
def read_builtin():
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
oct; oct; oct; oct; oct
def read_classvar():
A = _A
A.x = 1
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
A.x; A.x; A.x; A.x; A.x
def read_instancevar():
a = _A()
a.x = 1
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
a.x; a.x; a.x; a.x; a.x
def read_unboundmethod():
A = _A
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
A.m; A.m; A.m; A.m; A.m
def read_boundmethod():
a = _A()
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
a.m; a.m; a.m; a.m; a.m
def write_local():
v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
v_local = 1; v_local = 1; v_local = 1; v_local = 1; v_local = 1
def make_nonlocal_writer():
v_nonlocal = 1
def inner():
nonlocal v_nonlocal
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1; v_nonlocal = 1
return inner
write_nonlocal = make_nonlocal_writer()
def write_global():
global v_global
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
v_global = 1; v_global = 1; v_global = 1; v_global = 1; v_global = 1
def write_classvar():
A = _A
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
A.x = 1; A.x = 1; A.x = 1; A.x = 1; A.x = 1
def write_instancevar():
a = _A()
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
a.x = 1; a.x = 1; a.x = 1; a.x = 1; a.x = 1
if __name__=='__main__':
from timeit import timeit
for f in [read_local, read_nonlocal, read_global, read_builtin,
read_classvar, read_instancevar, read_unboundmethod, read_boundmethod,
write_local, write_nonlocal, write_global,
write_classvar, write_instancevar]:
print(timeit(f,number=1000000), f.__qualname__)

10
bench/fib.krk Normal file
View File

@ -0,0 +1,10 @@
def __main__():
def fib(n):
if n < 2: return n
return fib(n-2) + fib(n-1)
fib(30)
if __name__ == '__main__':
from timeit import timeit
print(timeit(__main__,number=1),'fib(30)')

10
bench/fib.py Normal file
View File

@ -0,0 +1,10 @@
def __main__():
def fib(n):
if n < 2: return n
return fib(n-2) + fib(n-1)
fib(30)
if __name__ == '__main__':
from timeit import timeit
print(timeit(__main__,number=1),'fib(30)')

11
bench/list.krk Normal file
View File

@ -0,0 +1,11 @@
from timeit import timeit
let l = []
let add = l.append
let pop = l.pop
def func():
add(1)
pop()
print(timeit(func), "list append")

11
bench/list.py Normal file
View File

@ -0,0 +1,11 @@
from timeit import timeit
l = []
add = l.append
pop = l.pop
def func():
add(1)
pop()
print(timeit(func), "list append")

14
bench/maketree.krk Normal file
View File

@ -0,0 +1,14 @@
class Node:
def __init__(self, left, right):
self.left = left
self.right = right
def makeTree(depth):
if depth <= 0: return Node(None,None)
let n1 = makeTree(depth-1)
let n2 = makeTree(depth-1)
return Node(n1,n2)
if __name__ == '__main__':
from timeit import timeit
print(timeit(lambda: makeTree(16), number=10), 'makeTree')

14
bench/maketree.py Normal file
View File

@ -0,0 +1,14 @@
class Node:
def __init__(self, left, right):
self.left = left
self.right = right
def makeTree(depth):
if depth <= 0: return Node(None,None)
n1 = makeTree(depth-1)
n2 = makeTree(depth-1)
return Node(n1,n2)
if __name__ == '__main__':
from timeit import timeit
print(timeit(lambda: makeTree(16), number=10), 'makeTree')