Blazing fast memoization library for JavaScript with comprehensive configuration options and React support
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Methods for collecting, analyzing, and managing memoization performance statistics to monitor cache effectiveness and optimize function performance.
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()); // trueGet 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%" }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: {} }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 profilesIndividual 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%" }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);