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