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