from time import time, sleep from random import Random from sys import stdout BASE = 2**15 MAX_POW = 2**4 MIN_POW = -MAX_POW MIN_SHIFT = 0 MAX_SHIFT = 1023 def minmax(vmin, value, vmax): if value < vmin: return vmin if value > vmax: return vmax return value def randint(vmin, vmax, index, width): value = (vmax - vmin) value *= index value //= (width - 1) value += vmin return value class Benchmark: def __init__(self): self.min_loop_duration = 0.100 self.min_loops = 25 self.random = Random() self.random.seed(1) self.integers = self.createIntegerSet() def createIntegerSet(self): positive = [] for n in range(100): positive.append(n) positive.append(2**n) positive.append(10**n) for diff in range(1, 4): positive.append(BASE - diff) positive.append(BASE + diff) positive.append(2**31 - diff) positive.append(2**31 + diff) positive.append(2**32 - diff) positive.append(2**32 + diff) positive.append(2**64 - diff) positive.append(2**64 + diff) randint = self.random.randint for index in range(1000): x = randint(0, 10) positive.append(x) x = randint(100, 10000) positive.append(x) x = randint(2**40, 2**200) positive.append(x) negative = [-x for x in positive] numbers = positive + negative self.random.shuffle(numbers) return tuple(numbers) def run_tests(self): for loop in range(5): self.test_integers() def test_integers(self): for index in range(len(self.integers)-1): a = self.integers[index] b = self.integers[index+1] x = abs(a) x = -a x = ~a x = abs(b) x = -b x = ~b x = a + b x = a - b x = a * b x = a + b x = a - b x = a * b POW = minmax(MIN_POW, b, MAX_POW) try: x = a ** POW except ZeroDivisionError: pass POW = minmax(MIN_POW, a, MAX_POW) try: x = b ** POW except ZeroDivisionError: pass try: x = a // b x = a / b x = a % b x = divmod(a, b) except ZeroDivisionError: pass try: x = b // a x = b / a x = b % a x = divmod(b, a) except ZeroDivisionError: pass shift = minmax(MIN_SHIFT, abs(b), MAX_SHIFT) x = a << shift x = a >> shift shift = minmax(MIN_SHIFT, abs(a), MAX_SHIFT) x = b << shift x = b >> shift x = str(a) x = int(str(a)) x = int(float(a)) x = str(b) x = int(str(b)) x = int(float(b)) def run(self): print("Python integer bench version 0.0") import sys value = 2147483647 sys.setcheckinterval(value) import gc gc.disable() tests = [] best = None while len(tests) < self.min_loops: stdout.write("Loop %s..." % (1 + len(tests))) stdout.flush() before = time() self.run_tests() after = time() diff = after - before if diff < self.min_loop_duration: raise ValueError("Your CPU is too fast, one loop (%.1f ms) is faster than %s ms" % (diff*1000, self.min_loop_duration*1000)) message = "%.1f ms" % (diff*1000) if best is None \ or (diff < best): best = diff message += " *BEST*" elif best is not None: error = (diff - best) * 100.0 / best message += " (%+.1f%%)" % error stdout.write(" %s\n" % message) tests.append(diff) best = min(min(tests), best) avg = sum(tests) / len(tests) worst = max(tests) print("Best: *** %.1f ms ***" % (best*1000)) print("Average: %.1f ms" % (avg*1000)) print("Worst: %.1f ms" % (worst*1000)) def main(): b = Benchmark() b.run() if __name__ == "__main__": main()