function memoize(fn) 
{
    // Create an object to store cached results.
    const cachedResult = {};

    // Return an anonymous function.
    return function() 
    {
        // Generate a unique key based on the function arguments.
        var key = JSON.stringify(arguments);

        // Check if the result for the current arguments is not cached.
        if (!cachedResult[key]) 
        {
            /*
                If not cached, compute the result by calling the 
                product function with the arguments.
            */
            cachedResult[key] = fn(...arguments);
        }
        // Return the cached result.
        return cachedResult[key];
    }
}


const product=(num1, num2)=>
{
    // Intentionally running the costly loop
    for(let i=0;i<10000000;i++){}

    // Returning the product
    return num1*num2;
}

const memoizedProduct=memoize(product)

console.time("1st Call")
console.log(memoizedProduct(22222,12345))
console.timeEnd("1st Call")

console.time("2nd Call")
console.log(memoizedProduct(22222,12345))
console.timeEnd("2nd Call")



//Output of 1st call
274330590
1st Call: 20.973ms

//Output of 2nd call
274330590
2nd Call: 0.278m