-
-
Notifications
You must be signed in to change notification settings - Fork 164
/
run_benchmark.py
89 lines (64 loc) · 2.93 KB
/
run_benchmark.py
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
# coding: UTF-8
""" Telco Benchmark for measuring the performance of decimal calculations
- http://speleotrove.com/decimal/telco.html
- http://speleotrove.com/decimal/telcoSpec.html
A call type indicator, c, is set from the bottom (least significant) bit of the duration (hence c is 0 or 1).
A rate, r, is determined from the call type. Those calls with c=0 have a low r: 0.0013; the remainder (‘distance calls’) have a ‘premium’ r: 0.00894. (The rates are, very roughly, in Euros or dollarates per second.)
A price, p, for the call is then calculated (p=r*n). This is rounded to exactly 2 fractional digits using round-half-even (Banker’s round to nearest).
A basic tax, b, is calculated: b=p*0.0675 (6.75%). This is truncated to exactly 2 fractional digits (round-down), and the total basic tax variable is then incremented (sumB=sumB+b).
For distance calls: a distance tax, d, is calculated: d=p*0.0341 (3.41%). This is truncated to exactly 2 fractional digits (round-down), and then the total distance tax variable is incremented (sumD=sumD+d).
The total price, t, is calculated (t=p+b, and, if a distance call, t=t+d).
The total prices variable is incremented (sumT=sumT+t).
The total price, t, is converted to a string, s.
"""
from decimal import ROUND_HALF_EVEN, ROUND_DOWN, Decimal, getcontext, Context
import io
import os
from struct import unpack
import pyperf
def rel_path(*path):
return os.path.join(os.path.dirname(__file__), *path)
def bench_telco(loops, filename):
getcontext().rounding = ROUND_DOWN
rates = list(map(Decimal, ('0.0013', '0.00894')))
twodig = Decimal('0.01')
Banker = Context(rounding=ROUND_HALF_EVEN)
basictax = Decimal("0.0675")
disttax = Decimal("0.0341")
with open(filename, "rb") as infil:
data = infil.read()
infil = io.BytesIO(data)
outfil = io.StringIO()
start = pyperf.perf_counter()
for _ in range(loops):
infil.seek(0)
sumT = Decimal("0") # sum of total prices
sumB = Decimal("0") # sum of basic tax
sumD = Decimal("0") # sum of 'distance' tax
for i in range(5000):
datum = infil.read(8)
if datum == '':
break
n, = unpack('>Q', datum)
calltype = n & 1
r = rates[calltype]
p = Banker.quantize(r * n, twodig)
b = p * basictax
b = b.quantize(twodig)
sumB += b
t = p + b
if calltype:
d = p * disttax
d = d.quantize(twodig)
sumD += d
t += d
sumT += t
print(t, file=outfil)
outfil.seek(0)
outfil.truncate()
return pyperf.perf_counter() - start
if __name__ == "__main__":
runner = pyperf.Runner()
runner.metadata['description'] = "Telco decimal benchmark"
filename = rel_path("data", "telco-bench.b")
runner.bench_time_func('telco', bench_telco, filename)