"""Benchmark Text hot paths: construction, copy, divide, render.""" import timeit import sys import os sys.path.insert(0, os.path.expanduser("~/rich")) def bench(label, stmt, setup, number=200_000): times = timeit.repeat(stmt, setup, number=number, repeat=5) best = min(times) per_call_ns = best / number * 1e9 print(f" {label}: {best*1000:.1f}ms total, {per_call_ns:.0f}ns/call ({number:,} iters, best of 5)") return best print(f"Python {sys.version}") print() common = """\ import sys, os sys.path.insert(0, os.path.expanduser("~/rich")) from rich.text import Text, Span from rich.style import Style from rich.console import Console """ # --- Text construction --- print("=== Text() construction ===") bench("Text('hello world')", "Text('hello world')", common) bench("Text('hello world', style='bold')", "Text('hello world', style='bold')", common) print() # --- Text.copy --- print("=== Text.copy() ===") copy_setup = common + "t = Text('hello world', style='bold')\nt.stylize('red', 0, 5)\n" bench("copy()", "t.copy()", copy_setup) print() # --- Text.blank_copy --- print("=== Text.blank_copy() ===") bench("blank_copy()", "t.blank_copy()", copy_setup) bench("blank_copy('new text')", "t.blank_copy('new text')", copy_setup) print() # --- Text.divide --- print("=== Text.divide() ===") div_setup = common + "t = Text('hello world, this is a longer text for divide testing')\nt.stylize('bold', 0, 5)\nt.stylize('red', 6, 11)\n" bench("divide([10, 20, 30])", "t.divide([10, 20, 30])", div_setup, number=100_000) print() # --- Text.render --- print("=== Text.render() ===") render_setup = common + """\ c = Console(width=80) t0 = Text('hello world') t1 = Text('hello world') t1.stylize('bold', 0, 5) t2 = Text('hello world') t2.stylize('bold', 0, 5) t2.stylize('red', 6, 11) """ bench("render (no spans)", "list(t0.render(c))", render_setup, number=100_000) bench("render (1 span)", "list(t1.render(c))", render_setup, number=100_000) bench("render (2 spans)", "list(t2.render(c))", render_setup, number=100_000) print() # --- E2E Console.print --- print("=== Console.print() E2E ===") print_setup = common + """\ import io c = Console(file=io.StringIO(), width=80) """ bench("print('hello')", "c.file.seek(0); c.print('hello')", print_setup, number=50_000) bench("print('[bold]hello[/bold]')", "c.file.seek(0); c.print('[bold]hello[/bold]')", print_setup, number=50_000) print("\nDone.")