[python] Checking whether a string starts with XXXX

I did a little experiment to see which of these methods

  • string.startswith('hello')
  • string.rfind('hello') == 0
  • string.rpartition('hello')[0] == ''
  • string.rindex('hello') == 0

are most efficient to return whether a certain string begins with another string.

Here is the result of one of the many test runs I've made, where each list is ordered to show the least time it took (in seconds) to parse 5 million of each of the above expressions during each iteration of the while loop I used:

['startswith: 1.37', 'rpartition: 1.38', 'rfind: 1.62', 'rindex: 1.62']
['startswith: 1.28', 'rpartition: 1.44', 'rindex: 1.67', 'rfind: 1.68']
['startswith: 1.29', 'rpartition: 1.42', 'rindex: 1.63', 'rfind: 1.64']
['startswith: 1.28', 'rpartition: 1.43', 'rindex: 1.61', 'rfind: 1.62']
['rpartition: 1.48', 'startswith: 1.48', 'rfind: 1.62', 'rindex: 1.67']
['startswith: 1.34', 'rpartition: 1.43', 'rfind: 1.64', 'rindex: 1.64']
['startswith: 1.36', 'rpartition: 1.44', 'rindex: 1.61', 'rfind: 1.63']
['startswith: 1.29', 'rpartition: 1.37', 'rindex: 1.64', 'rfind: 1.67']
['startswith: 1.34', 'rpartition: 1.44', 'rfind: 1.66', 'rindex: 1.68']
['startswith: 1.44', 'rpartition: 1.41', 'rindex: 1.61', 'rfind: 2.24']
['startswith: 1.34', 'rpartition: 1.45', 'rindex: 1.62', 'rfind: 1.67']
['startswith: 1.34', 'rpartition: 1.38', 'rindex: 1.67', 'rfind: 1.74']
['rpartition: 1.37', 'startswith: 1.38', 'rfind: 1.61', 'rindex: 1.64']
['startswith: 1.32', 'rpartition: 1.39', 'rfind: 1.64', 'rindex: 1.61']
['rpartition: 1.35', 'startswith: 1.36', 'rfind: 1.63', 'rindex: 1.67']
['startswith: 1.29', 'rpartition: 1.36', 'rfind: 1.65', 'rindex: 1.84']
['startswith: 1.41', 'rpartition: 1.44', 'rfind: 1.63', 'rindex: 1.71']
['startswith: 1.34', 'rpartition: 1.46', 'rindex: 1.66', 'rfind: 1.74']
['startswith: 1.32', 'rpartition: 1.46', 'rfind: 1.64', 'rindex: 1.74']
['startswith: 1.38', 'rpartition: 1.48', 'rfind: 1.68', 'rindex: 1.68']
['startswith: 1.35', 'rpartition: 1.42', 'rfind: 1.63', 'rindex: 1.68']
['startswith: 1.32', 'rpartition: 1.46', 'rfind: 1.65', 'rindex: 1.75']
['startswith: 1.37', 'rpartition: 1.46', 'rfind: 1.74', 'rindex: 1.75']
['startswith: 1.31', 'rpartition: 1.48', 'rfind: 1.67', 'rindex: 1.74']
['startswith: 1.44', 'rpartition: 1.46', 'rindex: 1.69', 'rfind: 1.74']
['startswith: 1.44', 'rpartition: 1.42', 'rfind: 1.65', 'rindex: 1.65']
['startswith: 1.36', 'rpartition: 1.44', 'rfind: 1.64', 'rindex: 1.74']
['startswith: 1.34', 'rpartition: 1.46', 'rfind: 1.61', 'rindex: 1.74']
['startswith: 1.35', 'rpartition: 1.56', 'rfind: 1.68', 'rindex: 1.69']
['startswith: 1.32', 'rpartition: 1.48', 'rindex: 1.64', 'rfind: 1.65']
['startswith: 1.28', 'rpartition: 1.43', 'rfind: 1.59', 'rindex: 1.66']

I believe that it is pretty obvious from the start that the startswith method would come out the most efficient, as returning whether a string begins with the specified string is its main purpose.

What surprises me is that the seemingly impractical string.rpartition('hello')[0] == '' method always finds a way to be listed first, before the string.startswith('hello') method, every now and then. The results show that using str.partition to determine if a string starts with another string is more efficient then using both rfind and rindex.

Another thing I've noticed is that string.rindex('hello') == 0 and string.rindex('hello') == 0 have a good battle going on, each rising from fourth to third place, and dropping from third to fourth place, which makes sense, as their main purposes are the same.

Here is the code:

from time import perf_counter

string = 'hello world'
places = dict()

while True:
    start = perf_counter()
    for _ in range(5000000):
        string.startswith('hello')
    end = perf_counter()
    places['startswith'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rfind('hello') == 0
    end = perf_counter()
    places['rfind'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rpartition('hello')[0] == ''
    end = perf_counter()
    places['rpartition'] = round(end - start, 2)

    start = perf_counter()
    for _ in range(5000000):
        string.rindex('hello') == 0
    end = perf_counter()
    places['rindex'] = round(end - start, 2)
    
    print([f'{b}: {str(a).ljust(4, "4")}' for a, b in sorted(i[::-1] for i in places.items())])

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to string-comparison

How do I compare two strings in python? How to compare the contents of two string objects in PowerShell String comparison in bash. [[: not found How do I compare version numbers in Python? Test if a string contains a word in PHP? Checking whether a string starts with XXXX comparing two strings in SQL Server Getting the closest string match How can I make SQL case sensitive string comparison on MySQL? String Comparison in Java