3 ms·
I wonder how would simply doing a `return min(heights)` compare to any of the options given? (It sure doesn't demonstrate the improvements between interpreter
by necovek 2y ago
I wonder how would simply doing a `return min(heights)` compare to any of the options given?
(It sure doesn't demonstrate the improvements between interpreter versions, but that's the classic, Python way of optimizing: let builtins do all the looping)
- necovek 2y agoI 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.
- otteromkram 2y agoNow try with a for loop.
- memco 2y agoFor science I added versions of the benchmarks as for loops: it's faster than the while loop versions above, but min(heights) is still way faster: def benchmark1for(heights): smallest = heights[0] for h in heights: if h < smallest: smallest = h return smallest def benchmark2for(heights): smallest = heights[0] for h in heights: smallest = min(h, smallest) return smallest Results: min(heights) : 0.07920974999433383 benchmark1 : 0.954568124958314 benchmark1for: 0.5765543330344371 benchmark2 : 1.8662503749947064 benchmark2for: 1.5281645830255002
- necovek 2y agoGood call GP, and thanks for the results! What was the Python version you used, and what was the CPU? My runs were on 3.11 on Ryzen 7 Pro 6850U with whatever the TDP envelope is on a Thinkpad T14s.
- memco 2y agoPython 3.12.1 on an M2 macbook air. For extra fun I also tested doing `sorted(heights)[0]` which is slightly faster than the benchmark2 variants, but slower than the benchmark1 variants.