which of these 2 quicksorts is faster?

Terry Reedy tjreedy at udel.edu
Wed Sep 10 22:38:23 CEST 2008



process wrote:
> qsort can handle bigger lists it seems, making less recursive calls
> before finishing(quicksort blows the stack when sorting
> range(100,-1000,-1).
> qsort does more work though right? is there a way to speed up that?

If you are worried about speed, these 'neat' functional definitions are 
*not* the way to go.  The standard in-place procedural version makes NO 
copies of the list and no concatenations of sorted pieces.  It also 
scans and partitions the list once instead of twice for each call.

> is the built-in sort not defined recursively?

Definition != implementation.  It is trivial to turn the second 
recursive call into iteration.  More work and an explicit stack (easy in 
Python) will do the same for the second.

> def quicksort(lista):
>     if len(lista) != 0:

For speed, don't 'sort' a list of length 1.  In fact, for speed, 
special-case lists of length 2 and possibly even longer 'short' lists.

>         return quicksort([x for x in lista[1:] if x < lista[0]]) +
> [lista[0]] + \
>                quicksort([x for x in lista[1:] if x >= lista[0]])
>     else:
>         return []
> 
> def qsort(lista):
>     l = len(lista)

In some fonts, 1 and l are extremely similar, so I initially read l/2 
below as 1/2.  Any of L or ln or n or sz would be clearer.

>     if len(lista) != 0:
>         return qsort([x for x in lista[:l/2]+lista[l/2+1:] if x <
> lista[l/2]]) + \
>                [lista[l/2]] + \
>                qsort([x for x in lista[:l/2]+lista[l/2+1:] if x >=
> lista[l/2]])
>     else:
>         return []

The difference between your versions is the deterministic choice of 
pivot element in the (reduncant) double partitioning.  It is generally 
better to pick one at random each time or possibly use the median value 
of the first, middle, and last.  Either way, a consistently bad choice 
that leads to unbalanced partitions and deep recursion is less likely.

Terry Jan Reedy




More information about the Python-list mailing list