Last active
January 17, 2020 21:39
-
-
Save kwikwag/1dc6ecf2688bb03cd4c062a654d0bad3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import timeit | |
from math import pow | |
import sys | |
# Python 2/3 compatible | |
# note : alternative versions of this file had pow(x,0.33) replaced with | |
# sqrt(x) or max(x,33,1,2,3,4,5,6,6,7,8,9) to see the effect of the | |
# number of arguments on run times. | |
class CallMe: | |
def __init__(self, context): | |
self.context = context | |
def __call__(self, *args, **kwargs): | |
return self.context(*args, **kwargs) | |
def call_me(func): | |
return lambda *args, **kwargs: func(*args, **kwargs) | |
print('Closure:') | |
print(timeit.timeit('[call_me(pow)(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import call_me')) | |
print('Class:') | |
print(timeit.timeit('[CallMe(pow)(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import CallMe')) | |
print('Bare call:') | |
print(timeit.timeit('[pow(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import CallMe')) | |
print(timeit.timeit('[pow(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import call_me')) | |
closu_call = call_me(pow) | |
class_call = CallMe(pow) | |
print(closu_call(77,0.33)) | |
print(class_call(77,0.33)) | |
print(pow(77,0.33)) | |
assert(closu_call(77,0.33) == class_call(77,0.33)) | |
assert(closu_call(77,0.33) == pow(77,0.33)) | |
print('Closure (prebuilt):') | |
print(timeit.timeit('[a(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import closu_call as a')) | |
print('Class (prebuilt):') | |
print(timeit.timeit('[a(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import class_call as a')) | |
print('Bare call:') | |
print(timeit.timeit('[pow(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import closu_call as a')) | |
print(timeit.timeit('[pow(n,0.33) for n in range(2000)]', number=2000, setup='from math import pow; from __main__ import class_call as a')) | |
try: # guppy wasn't able to install for Python 3 | |
from guppy import hpy | |
n = 1000000 | |
h = hpy() | |
print("Heap size before:") | |
print(h.heap().size) | |
print("Constructing many") | |
if len(sys.argv) > 1 and sys.argv[1] == '1': | |
print("...closures") | |
results = [ call_me(pow) for i in range(n) ] | |
else: | |
print("...callable classes") | |
results = [ CallMe(pow) for i in range(n) ] | |
h = hpy() | |
print("Heap size after:") | |
print(h.heap().size) | |
print(sum([ results[i](77,0.33) for i in range(n) ])) | |
except Exception as e: | |
print("Skipping heap size test because of exception: " + str(e)) | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
N.B. For python3 during installation of
guppy
you will be notified:And in Python 3.8.1 I got the following heap measurements:
232695531
for closures and160695531
for callable classes. Callable classes used 30% less memory :)