Python Quicksort - List Comprehension Vs Recursion (partition Routine)
Solution 1:
Why is list comprehension so much faster?
Because list comprehension implies C loop which is much faster than slow general way of using Python's
for
block.Some enlightenment on the limit on recursion in python. I first set it to 100000 in what cases should I be careful?
In case you run out of memory.
Trying to sort 1000000 elements hogged memory of my laptop (with the recursion method). What should I do if I want to sort so many elements? What kind of optimizations are possible?
Python's recursion gives such an overhead because every function call allocates a lot of stack memory space on each call.
In general, iteration is the answer (will give better performance in statistically 99% of use cases).
Talking about memory structures, if you have simple data structures, like chars, integers, floats: use built-in
array.array
which is much more memory efficient than alist
.
Solution 2:
Have you tried writing a non-recursive implementation of partition
? I suspect that the performance difference is purely the partition
implementation. You are recursing for each element in your implementation.
Update
Here's a quick implementation. It is still not super fast or even efficient, but it is much better than your original recursive one.
>>>defpartition(data):... pivot = data[0]... less, equal, greater = [], [], []...for elm in data:...if elm < pivot:... less.append(elm)...elif elm > pivot:... greater.append(elm)...else:... equal.append(elm)...return less, equal, greater...>>>defqsort2(data):...if data:... less, equal, greater = partition(data)...return qsort2(less) + equal + qsort2(greater)...return data...
I also think that there are a larger number of temporary lists generated in the "traditional" version.
Solution 3:
Try to compare the list comprehension to an in-place algorithm when the memory goes really big. The code below get a near execution time when sorting 100K integers numbers, but you will probably get stucked in the list comprehension solution when sorting 1M integers. I've made the tests using a 4Gb machine. The full code: http://snipt.org/Aaaje2
classQSort:
def__init__(self, lst):
self.lst = lst
defsorted(self):
self.qsort_swap(0, len(self.lst))
return self.lst
defqsort_swap(self, begin, end):
if (end - begin) > 1:
pivot = self.lst[begin]
l = begin + 1
r = end
while l < r:
if self.lst[l] <= pivot:
l += 1else:
r -= 1
self.lst[l], self.lst[r] = self.lst[r], self.lst[l]
l -= 1
self.lst[begin], self.lst[l] = self.lst[l], self.lst[begin]
# print begin, end, self.lst
self.qsort_swap(begin, l)
self.qsort_swap(r, end)
Post a Comment for "Python Quicksort - List Comprehension Vs Recursion (partition Routine)"