The reason method 2 is "faster" is because the values list is not reinstantiated after method 1 runs, so when method 2 runs, len(values)
is 1, so nothing happens.
If you reinstantiate, the two methods will take approximately the same amount of time:
import time
def add(x, y):
time.sleep(1)
return x + y
values = [1, 2, 3, 4, 5, 6, 7, 8]
start_time = time.time()
while len(values) > 1:
values = [add(values[0], values[1])] + values[2:]
print(values)
result = values[0]
print(result, time.time()-start_time)
values = [1, 2, 3, 4, 5, 6, 7, 8]
start_time = time.time()
while len(values) > 1:
values = values[2:] + [add(values[0], values[1])]
print(values)
result = values[0]
print(result, time.time()-start_time)
[3, 3, 4, 5, 6, 7, 8]
[6, 4, 5, 6, 7, 8]
[10, 5, 6, 7, 8]
[15, 6, 7, 8]
[21, 7, 8]
[28, 8]
[36]
36 7.014946937561035
[3, 4, 5, 6, 7, 8, 3]
[5, 6, 7, 8, 3, 7]
[7, 8, 3, 7, 11]
[3, 7, 11, 15]
[11, 15, 10]
[10, 26]
[36]
36 7.015171766281128
If you remove time.sleep(1)
and just add the two numbers natively, you will see that method #2 does appear to be faster:
import time
values = [1, 2, 3, 4, 5, 6, 7, 8]
start_time = time.time()
while len(values) > 1:
values = [values[0] + values[1]] + values[2:]
print(values)
result = values[0]
print(result, time.time()-start_time)
values = [1, 2, 3, 4, 5, 6, 7, 8]
start_time = time.time()
while len(values) > 1:
values = values[2:] + [values[0] + values[1]]
print(values)
result = values[0]
print(result, time.time()-start_time)
[3, 3, 4, 5, 6, 7, 8]
[6, 4, 5, 6, 7, 8]
[10, 5, 6, 7, 8]
[15, 6, 7, 8]
[21, 7, 8]
[28, 8]
[36]
36 7.319450378417969e-05
[3, 4, 5, 6, 7, 8, 3]
[5, 6, 7, 8, 3, 7]
[7, 8, 3, 7, 11]
[3, 7, 11, 15]
[11, 15, 10]
[10, 26]
[36]
36 2.7894973754882812e-05
However, if you wrap the core logic of the two methods in functions and run them multiple times, with a larger list, you can see that their runtime is basically the same:
import time
def method1(values):
start_time = time.time()
while len(values) > 1:
values = [values[0] + values[1]] + values[2:]
return time.time()-start_time
def method2(values):
start_time = time.time()
while len(values) > 1:
values = values[2:] + [values[0] + values[1]]
return time.time()-start_time
vals = list(range(1000))
average_1 = sum(method1(vals[:]) for _ in range(100))/100
average_2 = sum(method2(vals[:]) for _ in range(100))/100
print(average_1)
print(average_2)
0.0029142618179321287
0.0029442691802978515