1 #
2 # Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved.
3 # Modified and extended by Stefan Krah.
4 #
5
6 # Usage: ../../../python bench.py
7
8
9 import time
10 from test.support.import_helper import import_fresh_module
11
12 C = import_fresh_module('decimal', fresh=['_decimal'])
13 P = import_fresh_module('decimal', blocked=['_decimal'])
14
15 #
16 # NOTE: This is the pi function from the decimal documentation, modified
17 # for benchmarking purposes. Since floats do not have a context, the higher
18 # intermediate precision from the original is NOT used, so the modified
19 # algorithm only gives an approximation to the correctly rounded result.
20 # For serious use, refer to the documentation or the appropriate literature.
21 #
22 def pi_float():
23 """native float"""
24 lasts, t, s, n, na, d, da = 0, 3.0, 3, 1, 0, 0, 24
25 while s != lasts:
26 lasts = s
27 n, na = n+na, na+8
28 d, da = d+da, da+32
29 t = (t * n) / d
30 s += t
31 return s
32
33 def pi_cdecimal():
34 """cdecimal"""
35 D = C.Decimal
36 lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24)
37 while s != lasts:
38 lasts = s
39 n, na = n+na, na+8
40 d, da = d+da, da+32
41 t = (t * n) / d
42 s += t
43 return s
44
45 def pi_decimal():
46 """decimal"""
47 D = P.Decimal
48 lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24)
49 while s != lasts:
50 lasts = s
51 n, na = n+na, na+8
52 d, da = d+da, da+32
53 t = (t * n) / d
54 s += t
55 return s
56
57 def factorial(n, m):
58 if (n > m):
59 return factorial(m, n)
60 elif m == 0:
61 return 1
62 elif n == m:
63 return n
64 else:
65 return factorial(n, (n+m)//2) * factorial((n+m)//2 + 1, m)
66
67
68 print("\n# ======================================================================")
69 print("# Calculating pi, 10000 iterations")
70 print("# ======================================================================\n")
71
72 to_benchmark = [pi_float, pi_decimal]
73 if C is not None:
74 to_benchmark.insert(1, pi_cdecimal)
75
76 for prec in [9, 19]:
77 print("\nPrecision: %d decimal digits\n" % prec)
78 for func in to_benchmark:
79 start = time.time()
80 if C is not None:
81 C.getcontext().prec = prec
82 P.getcontext().prec = prec
83 for i in range(10000):
84 x = func()
85 print("%s:" % func.__name__.replace("pi_", ""))
86 print("result: %s" % str(x))
87 print("time: %fs\n" % (time.time()-start))
88
89
90 print("\n# ======================================================================")
91 print("# Factorial")
92 print("# ======================================================================\n")
93
94 if C is not None:
95 c = C.getcontext()
96 c.prec = C.MAX_PREC
97 c.Emax = C.MAX_EMAX
98 c.Emin = C.MIN_EMIN
99
100 for n in [100000, 1000000]:
101
102 print("n = %d\n" % n)
103
104 if C is not None:
105 # C version of decimal
106 start_calc = time.time()
107 x = factorial(C.Decimal(n), 0)
108 end_calc = time.time()
109 start_conv = time.time()
110 sx = str(x)
111 end_conv = time.time()
112 print("cdecimal:")
113 print("calculation time: %fs" % (end_calc-start_calc))
114 print("conversion time: %fs\n" % (end_conv-start_conv))
115
116 # Python integers
117 start_calc = time.time()
118 y = factorial(n, 0)
119 end_calc = time.time()
120 start_conv = time.time()
121 sy = str(y)
122 end_conv = time.time()
123
124 print("int:")
125 print("calculation time: %fs" % (end_calc-start_calc))
126 print("conversion time: %fs\n\n" % (end_conv-start_conv))
127
128 if C is not None:
129 assert(sx == sy)