Improve function performance that determines whether it is palindromic

Asked

Viewed 210 times

4

Objective: to optimize performance

Description of the problem:

I have a function that returns me if the word is a palindrome with true otherwise with `false, until then quiet, but need to improve function performance.

Code:

static bool checkPalindrome(string inputString) 
{
    
    if(inputString.Length>=1 && inputString.Length <= Math.Pow(10, 5))
     {
        string palindromo = "";

        for (Int32 i = inputString.Length-1; i >= 0; --i)
        {
                  palindromo += inputString[i];   
        }
         if (palindromo.ToLower().Equals(inputString.ToLower()))
             return true;
         else
             return false;
        
     }
     else
     {
        return false;
     }
}

2 answers

8


Not only is this code not idiomatic C# (it seems to be written in another language), it does a lot of needless things, including memory allocation.

The main change is not to allocate a new object which is something that can create a change problem, I only made comparisons because the problem only asks for it. And comparing one by one is the best way. Although it is not visible these methods you are using are composed of loops, they scan the entire data every time, it is very bad.

Another change is to leave as soon as you know that it is not palindrome, and it should occur a lot, it is easy not to be. When you already know it’s not have to continue the algorithm.

Finally, I only check halfway, because if I continue the result is already known. What would I differ from analyzing the first with the last and then the last with the first? It is the same.

I didn’t improve the validation because I don’t know the requirements.

using static System.Console;
                    
public class Program {
    public static void Main() {
        WriteLine(checkPalindrome("ana"));
        WriteLine(checkPalindrome("abba"));
        WriteLine(checkPalindrome("oki"));
    }
    static bool checkPalindrome(string inputString) {
        if(inputString.Length >= 1 && inputString.Length <= 100_000) {
            for (var i = 0; i < inputString.Length / 2; i++) if (char.ToLower(inputString[i]) != char.ToLower(inputString[inputString.Length - i - 1])) return false;
            return true;
        }
        return false;
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

  • Maniero after seeing your code saw how much my do things without need rs.. Thanks for the help!

1

My suggestion is this, first converts the String in a Array. Then reverse the Array. Lap String then make the comparison in uppercase letters.

public bool éPalindromo(string entrada)
{            
    return !string.IsNullOrEmpty(entrada) && new string(entrada.ToCharArray()
    .Reverse().ToArray()).ToUpper() == entrada.ToUpper();
}
  • 2

    This will make the performance immensely worse.

  • @Maniero explains something to me (it’s not a question, just a clarification). Won’t the c# Runtime create a Binder for each invoked method? These binders will not be stored a single callsite for ToCharArray().Reverse().ToArray(). So after the third flame the only methods that will have impact will not be string.IsNullOrEmpty, Callsitebinder.Bind() and input.Toupper()?

  • 1

    No, none of this exists. In fact what you are saying also makes no sense from a logical point of view. And the biggest problem is the memory allocation of various objects that are traversed several times. The only method that has no impact is what you said you will have. There are 6 loops (all allocate). His had 3, mine has 1 without allocation.

  • Take the performance test and see the fourth result.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.