f_global = """def fact_global(n):
global counter
counter += 1
if n == 1:
return 1
return n*fact_global(n-1)
fact_global({})"""
f_nonlocal = """def fact_nonlocal(n):
counter = 0
def __fact(n):
nonlocal counter
counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_nonlocal({})"""
f_attr = """def fact_attr(n):
fact_attr.counter = 0
def __fact(n):
fact_attr.counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_attr({})"""
import timeit
import statistics
tests = f_global, f_nonlocal, f_attr
tests = [
{'func': f_global, 'globals': {'counter': 0}},
{'func': f_nonlocal, 'globals': {}},
{'func': f_attr, 'globals': {}}]
for n in (10, 100, 860):
res_ordered = []
for test in tests:
res = timeit.repeat(test['func'].format(n), globals=test['globals'], repeat=5, number=10000)
stat = f"{statistics.mean(res):.5f} ± {statistics.stdev(res):.5f}"
res_ordered.append((test['func'].split(' ')[1].rstrip(), stat, statistics.mean(res)))
# message
print(f"{n=}")
print('\n'.join(f"{f}\t\t{stat}" for f, stat, _ in sorted(res_ordered, key=lambda t: t[-1])))
print()
f_global = """def fact_global(n):
global counter
counter += 1
if n == 1:
return 1
return n*fact_global(n-1)
fact_global({})"""
f_nonlocal = """def fact_nonlocal(n):
counter = 0
def __fact(n):
nonlocal counter
counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_nonlocal({})"""
f_attr = """def fact_attr(n):
fact_attr.counter = 0
def __fact(n):
fact_attr.counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_attr({})"""
tests = f_global, f_nonlocal, f_attr
tests = [
{'func': f_global, 'globals': {'counter': 0}},
{'func': f_nonlocal, 'globals': {}},
{'func': f_attr, 'globals': {}}]
import timeit
import statistics
for n in (10, 100, 860):
res_ordered = []
for test in tests:
res = timeit.repeat(test['func'].format(n), globals=test['globals'], repeat=5, number=1000)
stat = f"{statistics.mean(res):.5f} ± {statistics.stdev(res):.5f}"
res_ordered.append((test['func'].split(' ')[1].rstrip(), stat, statistics.mean(res)))
print(f"{n=}")
print('\n'.join(f"{f}\t\t{stat}" for f, stat, _ in sorted(res_ordered, key=lambda t: t[-1])))
print()
functools.lru_cache
f_global = """def fact_global(n):
global counter
counter += 1
if n == 1:
return 1
return n*fact_global(n-1)
fact_global({})"""
f_nonlocal = """def fact_nonlocal(n):
counter = 0
def __fact(n):
nonlocal counter
counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_nonlocal({})"""
f_attr = """def fact_attr(n):
fact_attr.counter = 0
def __fact(n):
fact_attr.counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
fact_attr({})"""
tests = f_global, f_nonlocal, f_attr
tests = [
{'func': f_global, 'globals': {'counter': 0}},
{'func': f_nonlocal, 'globals': {}},
{'func': f_attr, 'globals': {}}]
import timeit
n = 860
for test in tests:
res = timeit.repeat(test['func'].format(n), globals=test['globals'], repeat=5, number=1000)
print(test['func'].split(' ')[1], res)
def fact_global(n):
global counter
counter += 1
if n == 1:
return 1
return n*fact_global(n-1)
def fact_nonlocal(n):
counter = 0
def __fact(n):
nonlocal counter
counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
def fact_attr(n):
fact_attr.counter = 0
def __fact(n):
fact_attr.counter += 1
if n == 1:
return 1
return n*__fact(n-1)
res = __fact(n)
return res
def a():
global x
x += 1
import timeit
res = timeit.repeat(a, globals={'x': 0}, repeat=5, number=1000)
print(res)
quit()
tests = [{'func': fact_global, 'setup': {'counter': 0}},
{'func': fact_nonlocal, 'setup': {}},
{'func': fact_attr, 'setup': {}}]
tests = [{'func': fact_global, 'setup': {'counter': 0}}]
#tests = [{'func': fact_global, 'setup': "counter = 0;"}]
counter = 0
n = 16
import timeit
for test in tests:
#res = timeit.repeat(test['func'](n), setup=test['setup'], repeat=5, number=1000)
res = timeit.repeat(test['func'](n), globals=test['setup'], repeat=5, number=1000)
print(f.__name__, res)