Instantly share code, notes, and snippets.

Embed
What would you like to do?
from inspect import getsource
from timeit import timeit
from textwrap import dedent
# Generate a dict of all the valid printable two-character ASCII combinations
test_object = { }
DEFAULT_COUNT = 100_000
VALID_ASCII = range(0x20, 0x7F)
for character in VALID_ASCII:
for second in VALID_ASCII:
test_object[chr(character) + chr(second)] = character + second
class TestMethod:
# calling `str()` on a `TestMethod` object returns the source code of its
# `fun` attribute
def __str__(self):
return dedent("\n".join(getsource(self.fun).split("\n")[2:]))
# a wrapper for `self.fun` that assures that it returns `True`
def _run(self):
assert self.fun()
# run `fun` `count` number of times.
def run(self, count=DEFAULT_COUNT):
return timeit(lambda: self._run(), number=count) / count
# Fast and fastest change places depending on how many values are in the Dict
class Fast(TestMethod):
@staticmethod
def fun():
return test_object.get('d', 4) == 4
class Fastest(TestMethod):
@staticmethod
def fun():
# my personal choice
return (test_object.get('d') or 4) == 4
# not only is this the slowest (by almost twice as much) but it handles things
# in the most verbose way
class Slow(TestMethod):
@staticmethod
def fun():
try:
test_object['d']
return False
except KeyError as e:
if KeyError:
return True
def run(tests):
for test in tests.values():
test.results = test.run()
return tests
def time():
return run({ "fastest": Fastest(),
"fast": Fast(),
"slow": Slow() })
if __name__ == "__main__":
for method, test in time().items():
print("{} took {}ns per operation\nsource:\n{}\n".format(method, test.results * 1_000_000_000, test))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment