http://www.ics.uci.edu/~eppstein/161/960125.html
or maybe Blum, Floyd, Pratt, Rivest, and Tarjan if you're being fancy, which is 24N comparisons in the worst case (but more than 4N for the average case).
http://www.ics.uci.edu/~eppstein/161/960125.html
or maybe Blum, Floyd, Pratt, Rivest, and Tarjan if you're being fancy, which is 24N comparisons in the worst case (but more than 4N for the average case).
http://hg.python.org/cpython/file/3.4/Lib/statistics.py (line 296)
For lists of size 10M, I got a 7.3x speedup vs using the sorted function, and a 1.6x speedup vs using numpy.median. The sorted function was faster up until lists of size 100, presumably due to lower overhead. (The lazily-sorted list data-structure also keeps track of the pivots resulting from partitions, so that later method calls run faster by exploiting the partially-sorted structure that remains from earlier method calls).
Here's a plot of the time to compute the median for these different algorithms, (taken from a paper I wrote that's under review): http://imgur.com/oX1QLnS
So far I've tried median-of-medians, recursive quickselect, iterative quickselect tracking indices and partitioning in place, and heapq.nlargest. The implementation in Python 3.4.0 is both cleaner/easier to read and faster than anything I can make by an order of magnitude for 10,000 element lists. I'm sure someone else here can do better than me, but (s)he'd have a hard time beating CPython, imo.
The reason it's for non-primitives is because it's optimized for sorting lists where comparison is relatively expensive , such as the dereferencing Python does on every item and Java does for non-primitive items.
Thanks for putting the effort in and testing it! Very interesting results.
FWIW, here is some old timing data on a 2008 era Mac:
* approx timing on my Mac
* n, time in ms
* 10, <1
* 100, <1
* 1000, <1
* 10000, <1
* 100000, 30
* 1000000, 230
* 10000000, 2530
* 100000000, 33000
You are probably right that pure python will have trouble competing with a C sort, except for quite large N.http://legacy.python.org/dev/peps/pep-0450/
Note especially the pitfalls highlighted around naive diy solutions (not sure if this is actually taken care of in the module, but I hope so! :-).