I sorted four similar lists. List d consistently takes much longer than the others, which all take about the same time:
a: 33.5 ms
b: 33.4 ms
c: 36.4 ms
d: 110.9 ms
Why is that?
Test script (Attempt This Online!):
from timeit import repeat
n = 2_000_000
a = [i // 1 for i in range(n)] # [0, 1, 2, 3, ..., 1_999_999]
b = [i // 2 for i in range(n)] # [0, 0, 1, 1, 2, 2, ..., 999_999]
c = a[::-1] # [1_999_999, ..., 3, 2, 1, 0]
d = b[::-1] # [999_999, ..., 2, 2, 1, 1, 0, 0]
for name in 'abcd':
lst = globals()[name]
time = min(repeat(lambda: sorted(lst), number=1))
print(f'{name}: {time*1e3 :5.1f} ms')
As alluded to in the comments by btilly and Amadan, this is due to how the Timsort sorting algorithm works. Detailed description of the algorithm is here.
Timsort speeds up operation on partially sorted arrays by identifying runs of sorted elements.
Your arrays a, b and c each consist of just one run. The array d has 1 million runs.
The reason why the descending run cannot be
>=is to make the sort stable, i.e. keep the order of equal elements:Python 3.11 has slightly improved version of timsort, sometimes called powersort, but it uses the same run detection and thus has the same performance.