Konfusius wrote:I tested your heavily optimized array version count-inversions-6 on my PC and it still takes more than twice the time than the OPs version without a funcalled predicate (0.562 seconds vs 0.205 seconds). Maybe its just my hardware (Intel Pentium Dual-Core E5300 @ 2.60GHz) but all the arrays and declarations don't seem to help very much.
(defun comparator (a b)
(declare (type (fixnum a b))
(ftype (function (fixnum fixnum) boolean) comparator))
(< a b))
(defun count-inversions (source &optional (predicate #'comarator))
(declare (inline comparator)) ...)(defun count-inversions (lst &optional (predicate #'<))
(if (or (null lst) (null (cdr lst)))
0
(let* ((half (ceiling (/ (length lst) 2)))
(left-list (subseq lst 0 half))
(right-list (subseq lst half)))
(+ (loop for a fixnum in left-list
summing (loop for b fixnum in right-list
counting (not (< a b)))) ;(funcall predicate a b))))
(count-inversions left-list predicate)
(count-inversions right-list predicate)))))(defun make-big-hash-table (x)
(do* ((y (make-hash-table :size x))
(i 0 (1+ i)))
(nil)
(when (= x i) (return y))
(setf (gethash i y) (random 1000))))
(defun count-inversions-7 (table &optional (predicate #'<))
(let ((ht-size (hash-table-count table)))
(if (< ht-size 2)
0
(let* ((half (floor (/ ht-size 2)))
(right-table (split-hash-table table half)))
(+ (loop for a fixnum being the hash-values of table
summing
(loop for b fixnum being the hash-values of right-table
counting (not (< a b)))) ;(funcall predicate a b))))
(count-inversions-7 table predicate)
(count-inversions-7 right-table predicate))))))
(defun split-hash-table (table half)
(let ((result (make-hash-table)))
(maphash
#'(lambda (key value)
(when (>= key half)
(setf (gethash (- key half) result) value)
(remhash key table))) table) result))
(time (count-inversions-7 (make-big-hash-table 10000)))
;; Evaluation took:
;; 0.499 seconds of real time
;; 0.492031 seconds of total run time (0.492031 user, 0.000000 system)
;; 98.60% CPU
;; 1,397,445,267 processor cycles
;; 16,766,080 bytes consed
wvxvw wrote:Well, that shouldn't happen, because it doesn't make sense, or there must be very bad array implementation in both Clozure and CLISP. I mean, you can't beat O(1) with O(n), unless you do something very silly.
array access in Common Lisp is slow by design [...]
Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests