There are a lot of ways to check if string is a palindrome. Plenty of them listed here This question is not about "how" but rather about performance. I was assuing that is_palindrome should be twice faster than is_palindrome0 because it does len/2 iterations in the worst case. However, in reality, is_palindrome takes more than 30 seconds to check all the strings while is_palindrome0 gets the job done in less than half of a second! Test-case def is_palindrome(s): for i in range(len(s) // 2): if s != s[len(s)-i-1]: return 0 return 1 def is_palindrome0(s): if s == s[::-1]: return 1 else: return 0 N = 500 L = 99999 sss = '101' * L import time start = time.time() print(sum([1 for i in range(N) if is_palindrome0(sss+sss[i:])])) end = time.time() print(f'{(end - start):.2f}') start = time.time() print(sum([1 for i in range(N) if is_palindrome(sss+sss[i:])])) end = time.time() print(f'{(end - start):.2f}') Output 168 0.40 168 34.20 Any ideas why string slicing is so crazy fast? How to debug further? Apologies if I missed answered question with in-depth performance comparison. UPDATE. Taking into account Frank's comment. def is_palindrome(s): l = len(s) for i in range(l // 2): if s != s[l-i-1]: return 0 return 1 def is_palindrome0(s): if s == s[::-1]: return 1 else: return 0 N = 500 L = 99999 sss = '101' * L import time start = time.time() print(sum([1 for i in range(N) if is_palindrome0(sss+sss[i:])])) end = time.time() print(f'{(end - start):.2f}') start = time.time() print(sum([1 for i in range(N) if is_palindrome(sss+sss[i:])])) end = time.time() print(f'{(end - start):.2f}') A bit faster but still around 50x times slower. 168 0.41 168 25.11 Continue reading...