LBYL vs EAFP Timing Comparison
A simple experiment in Python comparing performance of two approaches to solve the same problem.
In the following examples, we will have a list named numbers
containing
integers from 0 to 4, and our task will be to remove all occurrences of
4
from the list in-place.
This will be the LBYL approach:
while 4 in numbers:
numbers.remove(4)
And this will be the EAFP approach:
while True:
try:
numbers.remove(4)
except ValueError:
break
In theory, the former approach should be less efficient compared to the latter because with each iteration, the loop condition will perform an additional item look-up in the list. Let’s verify this assumption.
Processing a short list
Scenario:
- list length: 5,000 items
- number of repetitions: 100,000
The timeit.timeit
function will be used to perform the operation
many times repeatedly and measure the execution time.
from timeit import timeit
setup = 'numbers = list(range(5)) * 1000'
lbyl_code = '''
while 4 in numbers:
numbers.remove(4)
'''
eafp_code = '''
while True:
try:
numbers.remove(4)
except ValueError:
break
'''
lbyl_time = timeit(lbyl_code, setup=setup, number=100_000)
eafp_time = timeit(eafp_code, setup=setup, number=100_000)
print(f'LBYL: {lbyl_time:.3f} s')
print(f'EAFP: {eafp_time:.3f} s')
Output of three sample runs of the program:
LBYL: 6.232 s
EAFP: 5.892 s
LBYL: 6.221 s
EAFP: 5.953 s
LBYL: 6.233 s
EAFP: 5.903 s
We can see that the try-except
approach is indeed faster, but the difference
is not significant.
Processing a long list
Scenario:
- list length: 50,000 items
- number of repetitions: 1
The codetiming
third-party library will be used to perform the
operation once without repetition and measure the execution time.
from codetiming import Timer
numbers = list(range(5)) * 10_000
with Timer(text='LBYL: {:.3f} s'):
while 4 in numbers:
numbers.remove(4)
numbers = list(range(5)) * 10_000
with Timer(text='EAFP: {:.3f} s'):
while True:
try:
numbers.remove(4)
except ValueError:
break
Output of three sample runs of the program:
LBYL: 6.104 s
EAFP: 2.999 s
LBYL: 6.334 s
EAFP: 3.010 s
LBYL: 6.099 s
EAFP: 3.008 s
We can see that the difference in execution time is significant in this case:
the try-except
approach is twice as faster.
Final note
The LBYL solution in this simple example is less efficient because of the
additional 4 in numbers
list item look-up. This operation’s average time
complexity is O(n)
.