/ profilers / profiler.js
profiler.js
  1  /**
  2   * Simple profiling utility for measuring function performance
  3   */
  4  
  5  /**
  6   * Profiles a function execution and returns timing information
  7   * @param {Function} fn - The function to profile
  8   * @param {Array} args - Arguments to pass to the function
  9   * @param {number} iterations - Number of iterations to run (default: 1)
 10   * @returns {Object} Profiling results with execution time statistics and the result from the last iteration
 11   */
 12  export function profileFunction(fn, args = [], iterations = 1) {
 13    if (typeof fn !== 'function') {
 14      throw new Error('First argument must be a function');
 15    }
 16  
 17    if (typeof iterations !== 'number' || iterations < 1) {
 18      throw new Error('Iterations must be a positive number');
 19    }
 20  
 21    const times = [];
 22    let results;
 23  
 24    for (let i = 0; i < iterations; i++) {
 25      const start = performance.now();
 26      results = fn(...args);
 27      const end = performance.now();
 28      times.push(end - start);
 29    }
 30  
 31    // Calculate statistics
 32    const total = times.reduce((sum, time) => sum + time, 0);
 33    const average = total / times.length;
 34    const min = Math.min(...times);
 35    const max = Math.max(...times);
 36  
 37    return {
 38      results, // Contains only the result from the last iteration
 39      stats: {
 40        iterations,
 41        totalTimeMs: total,
 42        averageTimeMs: average,
 43        minTimeMs: min,
 44        maxTimeMs: max,
 45        times
 46      }
 47    };
 48  }
 49  
 50  /**
 51   * Creates a profiled version of a function that logs performance metrics
 52   * @param {Function} fn - The function to profile
 53   * @param {string} fnName - Name of the function for logging
 54   * @param {Function} logger - Logger function (defaults to console.info)
 55   * @returns {Function} Profiled function that behaves like the original
 56   */
 57  export function createProfiledFunction(fn, fnName = 'anonymous', logger = console.info) {
 58    return function(...args) {
 59      const start = performance.now();
 60      const result = fn.apply(this, args);
 61      const end = performance.now();
 62      const executionTime = end - start;
 63  
 64      logger(`${fnName} executed in ${executionTime.toFixed(2)}ms`);
 65  
 66      return result;
 67    };
 68  }
 69  
 70  /**
 71   * Profiles an async function execution and returns timing information
 72   * @param {Function} asyncFn - The async function to profile
 73   * @param {Array} args - Arguments to pass to the function
 74   * @param {number} iterations - Number of iterations to run (default: 1)
 75   * @returns {Promise<Object>} Profiling results with execution time statistics and the result from the last iteration
 76   */
 77  export async function profileAsyncFunction(asyncFn, args = [], iterations = 1) {
 78    if (typeof asyncFn !== 'function') {
 79      throw new Error('First argument must be a function');
 80    }
 81  
 82    if (typeof iterations !== 'number' || iterations < 1) {
 83      throw new Error('Iterations must be a positive number');
 84    }
 85  
 86    const times = [];
 87    let results;
 88  
 89    for (let i = 0; i < iterations; i++) {
 90      const start = performance.now();
 91      results = await asyncFn(...args);
 92      const end = performance.now();
 93      times.push(end - start);
 94    }
 95  
 96    // Calculate statistics
 97    const total = times.reduce((sum, time) => sum + time, 0);
 98    const average = total / times.length;
 99    const min = Math.min(...times);
100    const max = Math.max(...times);
101  
102    return {
103      results, // Contains only the result from the last iteration
104      stats: {
105        iterations,
106        totalTimeMs: total,
107        averageTimeMs: average,
108        minTimeMs: min,
109        maxTimeMs: max,
110        times
111      }
112    };
113  }