-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrealTimeBenchmark.py
More file actions
85 lines (64 loc) · 2.77 KB
/
Copy pathrealTimeBenchmark.py
File metadata and controls
85 lines (64 loc) · 2.77 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
import time
from contextlib import contextmanager
import sys
class RealTimeBenchmark(object):
"""
This class runs realtime benchmarks on a series of functions
"""
def __init__(self):
super(RealTimeBenchmark, self).__init__()
self.benchmarks = {}
def __str__(self):
toRet = ""
sortedKeys = sorted(self.benchmarks.keys())
for key in sortedKeys:
toRet += "%s with %s -> time %f\n" % (key[0], key[1], self.benchmarks[key])
return toRet
def writeAsCSV(self, writable=sys.stdout, header=None):
"""
Write benchmark results in CSV file format to the given writable. If no writable
is given stdout is used.
"""
if header is None:
header = 'function, scale parameter, time\n'
else:
header += '\n' if '\n' not in header else ''
writable.write(header)
for key in sorted(self.benchmarks.keys()):
writable.write("%s, %s, %s\n" % (key[0], key[1], self.benchmarks[key]))
def benchmark(self, scalingFx=None, iter=None, *args):
"""
The given functions are iterated over, and each function is timed.
Scaling tests is possible by passing a context manager, and an iterable with a range of inputs to
pass as scaling args. The values yielded by the context manager are passed as args to the benchmarked
methods.
:param function scalingFx: A context manager that performs any necessary setup and teardown.
:param iter: an iterable of args to call scalingFx with.
:param function args: One or more functions to call _timedRun benchmarks on.
"""
if ((iter is None and scalingFx is not None) or
(iter is not None and scalingFx is None)):
raise RuntimeError('Both Scaling fxand iteration must be passed')
@contextmanager
def emptyContextManager(i):
yield None
scalingFx = scalingFx or emptyContextManager
iter = iter or [None]
for i in iter:
with scalingFx(i) as fxArgs:
for fx in args:
try:
# Keys for marks dict are tuples containing function name and scale value from iteration
self.benchmarks[(fx.__name__, i)] = self._timedRun(fx, *fxArgs)
except:
print("Function '%s' failed with scale value '%d' " % (fx.__name__, i))
def _timedRun(self, fx, *args):
"""
Times how long it takes to run the given function fx.
:param function fx: The function to run.
:return: The total time in seconds that it took to run
:rtype: int
"""
start = time.time()
fx(*args)
return time.time() - start