Coverage for perf.py: 65%

23 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-08 15:04 -0800

1"""Performance timing utilities for Vibelexity.""" 

2 

3from __future__ import annotations 

4 

5import time 

6from contextlib import contextmanager 

7 

8 

9@contextmanager 

10def time_block(): 

11 """Context manager to measure execution time in milliseconds.""" 

12 start = time.perf_counter() 

13 elapsed = [0.0] 

14 yield elapsed 

15 elapsed[0] = (time.perf_counter() - start) * 1000 

16 

17 

18TimingManager = dict[str, list[float]] 

19"""Type alias for timing manager: maps metric names to list of timings.""" 

20 

21 

22def create_timing_manager() -> TimingManager: 

23 """Create a new timing manager for collecting metric timings.""" 

24 return { 

25 "parse": [], 

26 "collect_functions": [], 

27 "cognitive": [], 

28 "halstead": [], 

29 "npath": [], 

30 "dtd": [], 

31 "cyclomatic": [], 

32 "lloc": [], 

33 "mi": [], 

34 "ldi": [], 

35 "duplication": [], 

36 } 

37 

38 

39def compute_stats(timings: list[float]) -> dict[str, float]: 

40 """Compute average and total for a list of timings.""" 

41 if not timings: 

42 return {"average_ms": 0.0, "total_ms": 0.0, "count": 0} 

43 return { 

44 "average_ms": round(sum(timings) / len(timings), 2), 

45 "total_ms": round(sum(timings), 2), 

46 "count": len(timings), 

47 } 

48 

49 

50def get_timing_summary(timing_manager: TimingManager) -> dict[str, dict[str, float]]: 

51 """Get summary statistics for all metrics.""" 

52 metrics = [ 

53 "parse", 

54 "collect_functions", 

55 "cognitive", 

56 "halstead", 

57 "npath", 

58 "dtd", 

59 "cyclomatic", 

60 "lloc", 

61 "mi", 

62 "ldi", 

63 "duplication", 

64 ] 

65 result = {} 

66 for metric in metrics: 

67 result[metric] = compute_stats(timing_manager.get(metric, [])) 

68 return result