andriyor
6/22/2017 - 10:21 PM

Python EAFP vs LBYL speeds

Python EAFP vs LBYL speeds

import reusables


@reusables.time_it()
def test_lbyl(messages):
    out = []
    for _ in range(10000):
        if messages and messages[0] and len(messages[0]) >= 3:
            out.append(messages[0][2])
    return out

@reusables.time_it()
def test_eafp(messages):
    out = []
    for _ in range(10000):
        try:
            out.append(messages[0][2])
        except IndexError:
            pass
    return out

if __name__ == '__main__':
    messages = [["hi there", "how are you?"]]
    assert len(test_lbyl(messages)) == len(test_eafp(messages))

    messages[0].append("I'm doing fine")
    assert len(test_lbyl(messages)) == len(test_eafp(messages))

    # LBYL is faster if the list isn't long enough, avoid an error and an attmepted append statement
    # Function 'test_lbyl' took a total of 0.0016206308322832311 seconds - args: ([['hi there', 'how are you?']],)
    # Function 'test_eafp' took a total of 0.0030271251617317893 seconds - args: ([['hi there', 'how are you?']],)
    
    # EAFP is faster when the success path is more common, avoiding the costly lookups  
    # Function 'test_lbyl' took a total of 0.0027111909965087614 seconds - args: ([['hi there', 'how are you?', "I'm doing fine"]],)
    # Function 'test_eafp' took a total of 0.001411011977187686 seconds - args: ([['hi there', 'how are you?', "I'm doing fine"]],)