import sys from typing import Self, cast import dataclasses @dataclasses.dataclass(slots=False) class Node: _parent: Self | None MessagePump = Node DOMNode = Node def mk_nodes(): node = Node(None) for i in range(1000000): node = Node(node) return node def ancestors_with_self_orig(self): nodes: list[MessagePump | None] = [self] add_node = nodes.append node: MessagePump | None = self while (node := node._parent) is not None: add_node(node) return cast("list[DOMNode]", nodes) def ancestors_with_self_orig_repeat_append_lookup(self): nodes: list[MessagePump | None] = [self] node: MessagePump | None = self while (node := node._parent) is not None: nodes.append(node) return cast("list[DOMNode]", nodes) def ancestors_with_self_traditional(self): nodes = [] node: Node | None = self while node is not None: nodes.append(node) node = node._parent return nodes def ancestors_with_self_traditional_while_true(self): nodes = [] node: Node | None = self while True: if node is None: return nodes nodes.append(node) node = node._parent def ancestors_with_self_traditional_while_true_break(self): nodes = [] node: Node | None = self while True: if node is None: break nodes.append(node) node = node._parent return nodes import pyperf def main(): runner = pyperf.Runner() runner.timeit(name="flatten a linked list with a walrus", stmt="demo.ancestors_with_self_orig(nodes)", setup="import demo; nodes = demo.mk_nodes()") runner.timeit(name="flatten a linked list with a walrus, nodes.append(node)", stmt="demo.ancestors_with_self_orig_repeat_append_lookup(nodes)", setup="import demo; nodes = demo.mk_nodes()") runner.timeit(name="flatten a linked list tradition", stmt="demo.ancestors_with_self_traditional(nodes)", setup="import demo; nodes = demo.mk_nodes()") runner.timeit(name="flatten a linked list tradition while true", stmt="demo.ancestors_with_self_traditional_while_true(nodes)", setup="import demo; nodes = demo.mk_nodes()") runner.timeit(name="flatten a linked list tradition while true break", stmt="demo.ancestors_with_self_traditional_while_true_break(nodes)", setup="import demo; nodes = demo.mk_nodes()") if __name__ == "__main__": sys.exit(main())