Skip to content

Instantly share code, notes, and snippets.

@nyggus
Created May 9, 2023 07:17
Show Gist options
  • Save nyggus/430a6ee05ea69cbd9e46c2d31ebedb95 to your computer and use it in GitHub Desktop.
Save nyggus/430a6ee05ea69cbd9e46c2d31ebedb95 to your computer and use it in GitHub Desktop.
import timeit
import pprint
import rounder # requires installation from PyPi
def compare(
__snippet1,
__snippet2,
*args,
number=10_000_000,
repeat=7,
setup="from collections import UserDict"):
snippets = [__snippet1, __snippet2, *args]
results = {}
for i, snippet in enumerate(snippets):
name = snippet if len(snippet) < 30 else f"snippet {i + 1}"
results[name] = min(timeit.repeat(
snippet, number=number, repeat=repeat, setup=setup
)) / number,
results = rounder.signif_object(results, digits=4)
pprint.pprint(results)
setup = """from collections import UserDict
from collections.abc import Sequence
from typing import Callable
def try_calculate(func: Callable, *args, **kwargs):
try:
return func(*args, **kwargs)
except TypeError:
return float("nan")
class RichDict(dict):
measures = {
"sum": sum,
"n": len,
"mean": lambda x: sum(x) / len(x),
}
def summarize(self):
statistics = {}
for k, v in self.items():
if isinstance(v, str):
statistics[k] = {"n": len(v)}
elif isinstance(v, Sequence):
statistics[k] = {
name: try_calculate(func, v)
for name, func
in self.measures.items()
}
return statistics
"""
compare("RichDict()", "dict()", "UserDict()", setup=setup)
###
compare(
"UserDict({i: i**2 for i in range(1000)})",
"RichDict({i: i**2 for i in range(1000)})",
"{i: i**2 for i in range(1000)}",
number=100_000,
setup=setup)
###
setup += """d = {'x': 1, 'y': 2, 'z': 3}
ud = UserDict(d)
rd = RichDict(d)
"""
compare("ud['x']", "rd['x']", "d['x']", setup=setup)
compare(
"ud.get('a', None)",
"rd.get('a', None)",
"d.get('a', None)",
setup=setup,
number=1_000_000)
###
compare("'a' in ud", "'a' in rd", "'a' in d", setup=setup, number=1_000_000)
###
setup += """d_loop = {str(i): i for i in range(100_000)}
ud_loop = UserDict(d)
rd_loop = RichDict(d)
"""
compare(
"for i, v in ud_loop.items(): pass",
"for i, v in rd_loop.items(): pass",
"for i, v in d_loop.items(): pass",
setup=setup,
number=10_000
)
###
setup += """
d = {str(i): i for i in range(100_000)}
rd = RichDict(d)
ud = UserDict(d)
"""
compare(
"for i, v in ud.items(): pass",
"for i, v in rd.items(): pass",
"for i, v in d.items(): pass",
setup=setup,
number=10
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment