forked from grantjenks/python-sortedcontainers
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark.py
More file actions
144 lines (116 loc) · 4 KB
/
Copy pathbenchmark.py
File metadata and controls
144 lines (116 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from __future__ import print_function
from sys import hexversion
import logging
import time, random, argparse
from functools import partial
try:
from collections import OrderedDict
except:
from ordereddict import OrderedDict
if hexversion < 0x03000000:
range = xrange
name_attr = 'func_name'
else:
name_attr = '__name__'
def detail(*values, **kwargs):
if not args.bare:
print(*values, **kwargs)
def measure(test, func, size):
start = time.clock()
test(func, size)
end = time.clock()
return (end - start)
def benchmark(test, name, ctor, setup, func_name, limit):
if args.load > 0:
load = args.load
ctor_original = ctor
def ctor_load():
obj = ctor_original()
obj._reset(load)
return obj
ctor = ctor_load
for size in sizes:
if not args.no_limit and size > limit:
continue
# warmup
obj = ctor()
setup(obj, size)
func = getattr(obj, func_name)
measure(test, func, size)
# record
times = []
for rpt in range(5):
obj = ctor()
setup(obj, size)
func = getattr(obj, func_name)
times.append(measure(test, func, size))
times.sort()
print(getattr(test, name_attr), name + args.suffix, size, times[0],
times[-1], times[2], sum(times) / len(times))
def register_test(func):
tests[getattr(func, name_attr)] = func
return func
def limit(test, kind, value):
if kind in impls[test]:
impls[test][kind]['limit'] = value
def remove(test, kind):
if kind in impls[test]:
del impls[test][kind]
tests = OrderedDict()
kinds = OrderedDict()
impls = OrderedDict()
sizes = []
lists = {}
parser = argparse.ArgumentParser(description='Benchmarking')
parser.add_argument('--seed', type=int, default=0,
help='seed value for random')
parser.add_argument('--no-limit', default=False, action='store_true',
help='no limit on size')
parser.add_argument('--test', action='append', help='filter tests by name')
parser.add_argument('--kind', action='append', help='filter types by name')
parser.add_argument('--size', type=int, action='append',
help='specify sizes to test')
parser.add_argument('--suffix', default='', help='suffix for kind name')
parser.add_argument('--bare', action='store_true', default=False,
help='hide header and footer info')
parser.add_argument('--load', type=int, default=0,
help='load value for sorted container types')
args = parser.parse_args()
def main(name):
global sizes, lists
detail('Benchmarking:', name)
detail('Seed:', args.seed)
random.seed(args.seed)
sizes.extend(args.size or [100, 1000, 10000, 100000, 1000000, 10000000])
detail('Sizes:', sizes)
lists.update((key, list(range(key))) for key in sizes)
for key in sizes:
random.shuffle(lists[key])
test_names = args.test or tests.keys()
kind_names = args.kind or kinds.keys()
detail('Tests:', list(test_names))
detail('Kinds:', list(kind_names))
detail('test_name', 'data_type', 'size', 'min', 'max', 'median', 'mean')
for test in impls:
if test not in test_names:
continue
for name in impls[test]:
if name not in kind_names:
continue
details = impls[test][name]
try:
benchmark(
tests[test],
name,
details['ctor'],
details['setup'],
details['func'],
details['limit'],
)
except Exception:
logging.exception('Benchmark Error')
logging.error('Test: %s', test)
logging.error('Name: %s', name)
for key in sorted(details):
logging.error('Details[%r]: %s', key, details[key])
detail('Benchmark Stop')