0

I am using following code to optimize the speed of the overall program execution. This program execution involves memoization. ( i.e. I am maintaining the results in an existing dictionary and using the results if the key is found , which causes in the normal recursion a complete tree.

However, while submitting the code at leetcode, i dont see any performance benifit. The runtime stays exactly in the same bracket and it does not provides any benifit.

Am I doing somehitng wrong?

Following with the memoization code :

Dictionary<long, string> memoizationDictionary = new Dictionary<long, string>();


string[] lessThanTwentyWords = new string[] { "","One","Two", "Three", "Four", "Five", "Six",
                                                  "Seven","Eight","Nine", "Ten","Eleven","Twelve",
                                                  "Thirteen","Fourteen","Fifteen","Sixteen",
                                                  "Seventeen","Eighteen","Nineteen"
                                            };

string[] tens = new string[] { "", "Ten", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
{
    long result = 1;
    long rem = 0;

    // Check if the result is already memoized
    if (memoizationDictionary.ContainsKey(num))
    {
        if( memoizationDictionary.TryGetValue(num, out var memoizedResult))
        {
            return memoizedResult;
        }
    }

    if (num == 0)
        return "";

    if (num >= 1 && num < 20)
    {
        memoizationDictionary[num] = lessThanTwentyWords[num];

        return memoizationDictionary[num];
    }

    if ((num / 1000000000) > 0)
    {
        rem = num % 1000000000;
        result = num / 1000000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 1000000) > 0)
    {
        rem = num % 1000000;
        result = num/1000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + 
                                     (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 1000) > 0)
    {
        rem = num % 1000;
        result = num/ 1000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 100) > 0)
    {
        rem = num % 100;
        result = num/100;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }
    else
    {
        if (num >= 20)
        {
            memoizationDictionary[num] = tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
            return memoizationDictionary[num];
        }

        return "";
    }    
}

While following is the normal recursive call code.

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
    {
        long result = 1;
        long rem = 0;

        if (num == 0)
        return "";
    
        if (num >= 1 && num < 20)
        return lessThanTwentyWords[num];

        if ((num / 1000000000) > 0)
        {
            rem = num % 1000000000;
            result = num / 1000000000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }

        if ((num / 1000000) > 0)
        {
            rem = num % 1000000;
            result = num/1000000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");        
        }

        if ((num / 1000) > 0)
        {
            rem = num % 1000;
            result = num/ 1000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }

        if ((num / 100) > 0)
        {
            rem = num % 100;
            result = num/100;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }
        else
        {
            if (num >= 20)
            {            
                return tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
            }

            return "";
        }    
    }

Following is the leet code performance indicator which was same(some time even better in old approach )

So far, I didn't try to investigate as the test cases of leetcode are not attainable.

8
  • 3
    How do you know that the part you optimized took a significant part of the runtime? Commented Jan 30, 2024 at 13:44
  • Yes, you are right, but I am just saving the results in the dictionary. No idea what input might cause the problem. It can be any number any long number in billions, or in millions or even small hundreds. Commented Jan 30, 2024 at 13:47
  • But do you think my saving and retrieving logic is bad? Commented Jan 30, 2024 at 13:47
  • Write a few benchmarks using benchmark.Net to check performance with different sequences of numbers . A profiler might also be handy. Even experienced programmers are often wrong when making assumptions about performance. The best method is to test and measure the impact of different changes. Commented Jan 30, 2024 at 13:57
  • 1
    are you sure that leetcode uses the same class instance in multiple tests? Commented Jan 30, 2024 at 13:59

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.