I was curious myself, so I've ran a quick benchmark:
import random
import timeit
heights = [random.randint(0, 10000)/100 for i in range(10000)]
def benchmark1(heights):
smallest = heights[0]
count = len(heights) - 1
while count > 0:
if heights[count] < smallest:
smallest = heights[count]
count -= 1
return smallest
def benchmark1b(heights):
a = 1
b = len(heights) - 1
min_height = heights[0]
while a < b:
if heights[a] < min_height:
min_height = heights[a]
a += 1
return min_height
def benchmark2(heights):
smallest = heights[0]
count = len(heights) - 1
while count > 0:
smallest = min(heights[count], smallest)
count -= 1
return smallest
print(timeit.timeit('min(heights)', number=1000, globals={'heights': heights}))
print(timeit.timeit('benchmark1(heights)', number=1000, globals={'heights': heights, 'benchmark1': benchmark1}))
print(timeit.timeit('benchmark1b(heights)', number=1000, globals={'heights': heights, 'benchmark1b': benchmark1b}))
print(timeit.timeit('benchmark2(heights)', number=1000, globals={'heights': heights, 'benchmark2': benchmark2}))
Here are the results in Python 3.11:
0.04471710091456771
0.21777329698670655
0.22779683792032301
0.6679719020612538
So, using min over a list is ~5x faster, using a single variable and a constant 0 is ~5% faster than using two for boundaries, and using min inside the loop instead of the if check is another 3 times slower: so, the old approach of looking for opportunities to use a builtin instead of looping still likely "wins" in the newer interpreters too, but if someone's got 3.14 alpha up, I'd love to see the results.
I might install 3.13 to check it out there too.