Created
December 19, 2016 10:31
-
-
Save PM2Ring/8f2cf8d5046d0873bb95ed71c1d05e45 to your computer and use it in GitHub Desktop.
Digit sum speed tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
''' Sum the digits of a non-negative integer | |
Speed tests of various implementations | |
Written by PM 2Ring & hiro protagonist 2016.12.19 | |
sum_digits_hiro is faster than sum_digits_pm_map until digits=20 | |
in Python 3.6 and digits=60 in Python 2.6 | |
For large numbers of digits, sum_digits_pm_dict is the fastest | |
''' | |
from __future__ import print_function, division | |
from timeit import Timer | |
def sum_digits_hiro(n): | |
count = 0 | |
while n: | |
count += n % 10 | |
n //= 10 | |
return count | |
def sum_digits_pm_gen(n): | |
return sum(int(d) for d in str(n)) | |
def sum_digits_pm_map(n): | |
return sum(map(int, str(n))) | |
def sum_digits_pm_ord(n): | |
return sum(ord(d)-48 for d in str(n)) | |
def sum_digits_pm_dict(n, | |
digit={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}): | |
return sum(digit[d] for d in str(n)) | |
funcs = ( | |
sum_digits_hiro, | |
sum_digits_pm_gen, | |
sum_digits_pm_map, | |
sum_digits_pm_ord, | |
sum_digits_pm_dict, | |
) | |
def verify(): | |
results = [[func(n) for n in data] for func in funcs] | |
func = funcs[0] | |
first = [func(n) for n in data] | |
print(all(first == [func(n) for n in data] for func in funcs[1:])) | |
def time_test(loops, reps): | |
''' Print timing stats for all the functions ''' | |
timings = [] | |
for func in funcs: | |
fname = func.__name__ | |
setup = 'from __main__ import data, ' + fname | |
cmd = 'for n in data: {0}(n)'.format(fname) | |
t = Timer(cmd, setup) | |
result = t.repeat(reps, loops) | |
result.sort() | |
timings.append((result, fname)) | |
timings.sort() | |
for result, fname in timings: | |
print('{0:18} {1}'.format(fname, result)) | |
digits = 20 | |
lo = 10**(digits-1) | |
print('digits:', digits) | |
data = range(lo, lo + 1000) | |
#verify() | |
time_test(loops=20, reps=3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment