[armedbear-cvs] r13852 - trunk/abcl/src/org/armedbear/lisp

mevenson at common-lisp.net mevenson at common-lisp.net
Sat Feb 4 19:08:04 UTC 2012


Author: mevenson
Date: Sat Feb  4 11:08:03 2012
New Revision: 13852

Log:
CL:SORT implementation replace non-optimal quicksort with public version.

With these changes, SORT seems to be a little faster (for vectors)
although I was not worried with optimizations. In ABCL 1.0.1, in my
machine, sorting 1000000 random integers takes around 10s on average
while now it takes 2s. However, I must point out I didn't do any
serious and proper benchmarking, just some runs.

I will be happy to answer any questions if necessary.

Cheers,
Jorge Tavares

Modified:
   trunk/abcl/src/org/armedbear/lisp/sort.lisp

Modified: trunk/abcl/src/org/armedbear/lisp/sort.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/sort.lisp	Sat Feb  4 07:53:21 2012	(r13851)
+++ trunk/abcl/src/org/armedbear/lisp/sort.lisp	Sat Feb  4 11:08:03 2012	(r13852)
@@ -36,7 +36,7 @@
 (defun sort (sequence predicate &rest args &key key)
   (sequence::seq-dispatch sequence
     (sort-list sequence predicate key)
-    (quick-sort sequence 0 (length sequence) predicate key)
+    (quicksort sequence 0 (1- (length sequence)) predicate (or key #'identity))
     (apply #'sequence:sort sequence predicate args)))
 
 (defun stable-sort (sequence predicate &rest args &key key)
@@ -182,6 +182,56 @@
         (if (eq list-1 (cdr head))
             (return list-1))))))
 
+#|
+<> dc:author "Jorge Tavares" ;
+    dc:description 
+""" 
+The quicksort function picks the pivot by selecting a midpoint and
+also sorts the smaller partition first. These are enough to avoid the
+stack overflow problem as reported. I've performed some tests and it
+looks it is correct 
+"""" .
+|#
+;;;
+;;; QUICKSORT
+;;; - the pivot is a middle point
+;;; - sorts the smaller partition first
+;;;
+(defun quicksort (vector start end predicate key)
+  (declare (type fixnum start end)
+	   (type function predicate key))
+  (if (< start end)
+      (let* ((i start)
+	     (j (1+ end))
+	     (p (+ start (ash (- end start) -1)))
+	     (d (aref vector p))
+	     (kd (funcall key d)))
+	(rotatef (aref vector p) (aref vector start))
+	(block outer-loop
+	  (loop
+	    (loop 
+	      (unless (> (decf j) i) (return-from outer-loop))
+	      (when (funcall predicate 
+			     (funcall key (aref vector j)) kd)
+		(return)))
+	    (loop 
+	      (unless (< (incf i) j) (return-from outer-loop))
+	      (unless (funcall predicate
+			       (funcall key (aref vector i)) kd)
+		(return)))
+	    (rotatef (aref vector i) (aref vector j))))
+	(setf (aref vector start) (aref vector j)
+	      (aref vector j) d)
+	(if (< (- j start) (- end j))
+	    (progn
+	      (quicksort vector start (1- j) predicate key)
+	      (quicksort vector (1+ j) end predicate key))
+	    (progn
+	      (quicksort vector (1+ j) end predicate key)
+	      (quicksort vector start (1- j) predicate key))))
+      vector))
+
+;;; DEPRECATED -- to be removed in abcl-1.4
 ;;; From ECL.
 (defun quick-sort (seq start end pred key)
   (unless key (setq key #'identity))




More information about the armedbear-cvs mailing list