"""Runtime timing helpers for EPUB search.""" from __future__ import annotations from dataclasses import dataclass from time import perf_counter from typing import TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Callable @dataclass(frozen=True) class RuntimeStep: """Elapsed runtime for one named search step.""" name: str duration_ms: float counts_toward_total: bool = True def runtime_step_from_start(name: str, start_seconds: float) -> RuntimeStep: """Create a runtime step from a prior perf_counter timestamp.""" return RuntimeStep(name=name, duration_ms=(perf_counter() - start_seconds) * 1000) def timed_result[T, **P]( name: str, operation: Callable[P, T], *args: P.args, **kwargs: P.kwargs, ) -> tuple[T, RuntimeStep]: """Run an operation and return its result plus elapsed runtime.""" start_seconds = perf_counter() result = operation(*args, **kwargs) return result, runtime_step_from_start(name, start_seconds)