CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-moize

Blazing fast memoization library for JavaScript with comprehensive configuration options and React support

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

statistics-profiling.mddocs/

Statistics and Profiling

Methods for collecting, analyzing, and managing memoization performance statistics to monitor cache effectiveness and optimize function performance.

Capabilities

Statistics Collection Control

Enable or disable global statistics collection for all memoized functions.

/**
 * Enable or disable statistics collection globally
 * @param isCollectingStats Whether to collect statistics (default: true)
 */
collectStats(isCollectingStats?: boolean): void;

/**
 * Check if statistics are currently being collected
 * @returns Whether statistics collection is enabled
 */
isCollectingStats(): boolean;

Usage Examples:

import moize from "moize";

// Enable statistics collection
moize.collectStats(true);
console.log(moize.isCollectingStats()); // true

// Create memoized functions (stats will be collected)
const add = (a: number, b: number) => a + b;
const memoizedAdd = moize(add);

// Disable statistics collection
moize.collectStats(false);
console.log(moize.isCollectingStats()); // false

// Re-enable with explicit call
moize.collectStats();
console.log(moize.isCollectingStats()); // true

Statistics Retrieval

Get performance statistics for specific profiles or global statistics.

/**
 * Get statistics for a specific profile or global statistics
 * @param profileName Optional profile name to get specific stats
 * @returns Statistics object with calls, hits, and usage percentage
 */
getStats(profileName?: string): StatsObject;

type StatsObject = {
  calls: number;      // Total number of function calls
  hits: number;       // Number of cache hits
  usage: string;      // Hit rate as percentage string
};

type GlobalStatsObject = StatsObject & {
  profiles?: Record<string, StatsProfile>;  // Individual profile statistics
};

type StatsProfile = {
  calls: number;
  hits: number;
};

Usage Examples:

import moize from "moize";

moize.collectStats(true);

// Create profiled memoized functions
const fibonacci = (n: number): number => {
  if (n < 2) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
};

const memoizedFib = moize.profile('fibonacci')(fibonacci);

const factorial = (n: number): number => {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
};

const memoizedFactorial = moize.profile('factorial').maxSize(20)(factorial);

// Use the functions to generate stats
memoizedFib(10);
memoizedFib(10); // Cache hit
memoizedFib(15);
memoizedFactorial(5);
memoizedFactorial(5); // Cache hit

// Get global statistics
const globalStats = moize.getStats();
console.log(globalStats);
// {
//   calls: 6,
//   hits: 2,
//   usage: "33.33%",
//   profiles: {
//     fibonacci: { calls: 3, hits: 1 },
//     factorial: { calls: 2, hits: 1 }
//   }
// }

// Get specific profile statistics
const fibStats = moize.getStats('fibonacci');
console.log(fibStats);
// { calls: 3, hits: 1, usage: "33.33%" }

const factorialStats = moize.getStats('factorial');
console.log(factorialStats);
// { calls: 2, hits: 1, usage: "50.00%" }

Statistics Clearing

Clear statistics for specific profiles or all statistics.

/**
 * Clear statistics for a specific profile or all statistics
 * @param profileName Optional profile name to clear specific stats
 */
clearStats(profileName?: string): void;

Usage Examples:

import moize from "moize";

moize.collectStats(true);

const processData = (data: any[]) => data.map(x => x * 2);
const memoizedProcess = moize.profile('data-processing')(processData);

// Generate some statistics
memoizedProcess([1, 2, 3]);
memoizedProcess([1, 2, 3]); // Hit
memoizedProcess([4, 5, 6]);

console.log(moize.getStats('data-processing'));
// { calls: 3, hits: 1, usage: "33.33%" }

// Clear specific profile stats
moize.clearStats('data-processing');
console.log(moize.getStats('data-processing'));
// { calls: 0, hits: 0, usage: "0.00%" }

// Clear all statistics
moize.clearStats();
console.log(moize.getStats());
// { calls: 0, hits: 0, usage: "0.00%", profiles: {} }

Profile Assignment

Assign profile names to memoized functions for organized statistics tracking.

/**
 * Create a moizer with a specific profile name for statistics tracking
 * @param profileName Name to identify this group of memoized functions
 * @returns Moizer with profile name configuration
 */
profile<ProfileName extends string>(
  profileName: ProfileName
): Moizer<{ profileName: ProfileName }>;

Usage Examples:

import moize from "moize";

moize.collectStats(true);

// API-related functions
const fetchUser = async (id: string) => {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
};

const fetchPosts = async (userId: string) => {
  const response = await fetch(`/api/posts?userId=${userId}`);
  return response.json();
};

// Group under 'api-calls' profile
const memoizedFetchUser = moize.promise.profile('api-calls')(fetchUser);
const memoizedFetchPosts = moize.promise.profile('api-calls')(fetchPosts);

// Math operations
const isPrime = (n: number): boolean => {
  if (n < 2) return false;
  for (let i = 2; i <= Math.sqrt(n); i++) {
    if (n % i === 0) return false;
  }
  return true;
};

const fibonacci = (n: number): number => {
  if (n < 2) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
};

// Group under 'math' profile
const memoizedIsPrime = moize.profile('math')(isPrime);
const memoizedFibonacci = moize.profile('math')(fibonacci);

// Use functions to generate statistics
await memoizedFetchUser('123');
await memoizedFetchPosts('123');
memoizedIsPrime(17);
memoizedFibonacci(10);

// Check profile-specific statistics
console.log(moize.getStats('api-calls'));
console.log(moize.getStats('math'));
console.log(moize.getStats()); // Global stats with all profiles

Instance-Level Statistics

Individual memoized functions also provide their own statistics methods.

interface Moized {
  /**
   * Clear statistics for this specific memoized function
   */
  clearStats(): void;
  
  /**
   * Get statistics for this specific memoized function
   * @returns Profile statistics for this function
   */
  getStats(): StatsProfile;
  
  /**
   * Check if this function is collecting statistics
   * @returns Whether this function collects statistics
   */
  isCollectingStats(): boolean;
}

Usage Examples:

import moize from "moize";

moize.collectStats(true);

const expensiveCalculation = (n: number) => {
  // Simulate expensive computation
  let result = 0;
  for (let i = 0; i < n * 1000; i++) {
    result += Math.sqrt(i);
  }
  return result;
};

const memoized = moize.maxSize(10).profile('expensive-calc')(expensiveCalculation);

// Use the function multiple times
memoized(100);  // Computed
memoized(100);  // Hit
memoized(200);  // Computed
memoized(100);  // Hit

// Get instance-specific statistics
console.log(memoized.getStats());
// { calls: 4, hits: 2 }

console.log(memoized.isCollectingStats()); // true

// Clear instance statistics
memoized.clearStats();
console.log(memoized.getStats());
// { calls: 0, hits: 0 }

// This also affects the global profile stats
console.log(moize.getStats('expensive-calc'));
// { calls: 0, hits: 0, usage: "0.00%" }

Monitoring Cache Effectiveness

Use statistics to monitor and optimize cache performance.

import moize from "moize";

// Helper function to analyze cache effectiveness
function analyzeCachePerformance(profileName: string) {
  const stats = moize.getStats(profileName);
  
  if (stats.calls === 0) {
    console.log(`${profileName}: No function calls recorded`);
    return;
  }
  
  const hitRate = (stats.hits / stats.calls) * 100;
  
  console.log(`${profileName} Performance:`);
  console.log(`  Total calls: ${stats.calls}`);
  console.log(`  Cache hits: ${stats.hits}`);
  console.log(`  Hit rate: ${hitRate.toFixed(2)}%`);
  
  if (hitRate < 20) {
    console.log(`  ⚠️  Low hit rate - consider adjusting cache size or TTL`);
  } else if (hitRate > 80) {
    console.log(`  ✅ Excellent hit rate - cache is very effective`);
  } else {
    console.log(`  📊 Moderate hit rate - cache is working but could be optimized`);
  }
}

moize.collectStats(true);

// Set up monitored functions
const apiCall = moize.promise.profile('api').maxAge(30000)(async (endpoint: string) => {
  const response = await fetch(endpoint);
  return response.json();
});

const computation = moize.profile('computation').maxSize(50)(
  (data: number[]) => data.reduce((sum, val) => sum + Math.pow(val, 2), 0)
);

// After using the functions, analyze performance
setTimeout(() => {
  analyzeCachePerformance('api');
  analyzeCachePerformance('computation');
}, 10000);

docs

argument-transformation.md

cache-introspection.md

cache-management.md

core-memoization.md

equality-comparison.md

index.md

specialized-memoization.md

statistics-profiling.md

utility-methods.md

tile.json