All files / src/internal profiler.ts

100% Statements 40/40
100% Branches 14/14
100% Functions 4/4
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                          1x 1x 1x 1x 1x           1x 8x 8x   5x 5x 5x 5x 5x 8x   1x 355x 355x   1x 355x 5x 5x 7x   7x 355x 355x 355x 355x         1x 6x 6x 3x 6x   6x 6x 6x 6x 6x 6x 6x 6x  
/**
 * Performance Profiling Hooks for Aided.
 * Provides zero-overhead (when disabled) tracking of effect execution times.
 */
 
export interface ProfilerReport {
  effectExecutions: number;
  totalTimeMs: number;
  averageTimeMs: number;
  maxTimeMs: number;
  effects: Record<string, { count: number; totalTimeMs: number }>;
}
 
let isProfiling = false;
let totalExecutions = 0;
let totalTime = 0;
let maxTime = 0;
const effectStats = new Map<string, { count: number; totalTime: number }>();
 
/**
 * Enables or disables the reactive effect profiler.
 * When disabled, profiling overhead is reduced to a single boolean check.
 */
export function enableProfiler(enable: boolean = true): void {
  isProfiling = enable;
  if (!enable) {
    // Reset stats when disabled to keep memory clean
    totalExecutions = 0;
    totalTime = 0;
    maxTime = 0;
    effectStats.clear();
  }
}
 
export function isProfilerEnabled(): boolean {
  return isProfiling;
}
 
export function recordEffectExecution(name: string, durationMs: number): void {
  if (!isProfiling) return;
  totalExecutions++;
  totalTime += durationMs;
  if (durationMs > maxTime) maxTime = durationMs;
 
  const stats = effectStats.get(name) || { count: 0, totalTime: 0 };
  stats.count++;
  stats.totalTime += durationMs;
  effectStats.set(name, stats);
}
 
/**
 * Generates a snapshot report of all tracked effect executions.
 */
export function getProfilerReport(): ProfilerReport {
  const effects: Record<string, { count: number; totalTimeMs: number }> = {};
  effectStats.forEach((stats, name) => {
    effects[name] = { count: stats.count, totalTimeMs: stats.totalTime };
  });
 
  return {
    effectExecutions: totalExecutions,
    totalTimeMs: totalTime,
    averageTimeMs: totalExecutions > 0 ? totalTime / totalExecutions : 0,
    maxTimeMs: maxTime,
    effects
  };
}