Skip to content

Instantly share code, notes, and snippets.

@dutc
Last active October 21, 2022 21:16
Show Gist options
  • Save dutc/38ea08a0bb6693cd9f7507421ac8e62b to your computer and use it in GitHub Desktop.
Save dutc/38ea08a0bb6693cd9f7507421ac8e62b to your computer and use it in GitHub Desktop.
A timing context manager.
from dataclasses import dataclass, field, replace
from collections import namedtuple, defaultdict
from itertools import count
from collections.abc import Generator
from contextlib import contextmanager
from time import perf_counter
from networkx import DiGraph
@dataclass(frozen=True)
class timer:
measure : Generator = (perf_counter() for _ in count())
labels : Generator = field(default_factory=count)
measurements : list = field(default_factory=list)
parent : int = -1
Measurement = namedtuple('MeasurementBase', 'label parent value')
@property
@contextmanager
def lap(self):
self.measurements.append(
self.Measurement(lbl := next(self.labels), parent := self.parent, next(self.measure))
)
try:
yield replace(self, parent=lbl)
finally:
self.measurements.append(
self.Measurement(lbl, parent, next(self.measure))
)
class Interval(namedtuple('IntervalBase', 'start stop')):
delta = property(lambda self: self.stop.value - self.start.value)
__iter__ = lambda self: iter(self.measurements)
def traverse(self, *, root=(_root := object())):
def dfs(n, *, depth=-1):
if n is not root:
yield depth, n
for n in g[n]:
yield from dfs(n, depth=depth+1)
g = self.as_graph
return dfs(root)
@property
def as_graph(self):
nodes = defaultdict(list)
for m in self:
nodes[m.label].append(m)
nodes = {k: self.Interval(*ns) for k, ns in nodes.items()}
(g := DiGraph()).add_edges_from(
(nodes.get(n.start.parent, self._root), n) for n in nodes.values()
)
return g
if __name__ == '__main__':
from time import sleep
with timer().lap as t:
sleep(.1)
with t.lap as t1:
sleep(.2)
with t1.lap:
sleep(.3)
with t.lap as t1:
sleep(.2)
for depth, intvl in t.traverse():
print(f'{"":<{depth * 4}} \N{mathematical bold capital delta}t: {intvl.delta:.2f}s')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment