1.0.4.87: better EQUALP hash function for arrays
authorJuho Snellman <jsnell@iki.fi>
Sat, 14 Apr 2007 12:28:15 +0000 (12:28 +0000)
committerJuho Snellman <jsnell@iki.fi>
Sat, 14 Apr 2007 12:28:15 +0000 (12:28 +0000)
        * Hashing on just the first 4 elements makes EQUALP tables essentially
          useless for many kinds of data due to collisions. Hash all the
          elements.
        * Optimize a couple of other cases that are probably common
          (u-b 8 vectors, fixnum vectors).
        * Change EQUALP-HASH to punt to EQ-HASH when appropriate

src/code/sxhash.lisp
src/code/target-hash-table.lisp
src/code/target-sxhash.lisp
src/compiler/fndb.lisp
version.lisp-expr

index 53431b2..dde2e15 100644 (file)
                   (%set-symbol-hash x sxhash)
                   sxhash)
                 result)))))
+
+(deftransform psxhash ((x &optional depthoid) (character &optional t))
+  `(char-code (char-upcase x)))
+
+(deftransform psxhash ((x &optional depthoid) (integer &optional t))
+  `(sxhash x))
index d6c7560..c25c730 100644 (file)
 
 (defun equalp-hash (key)
   (declare (values hash (member t nil)))
-  (values (psxhash key) nil))
+  (typecase key
+    ;; Types requiring special treatment. Note that PATHNAME and
+    ;; HASH-TABLE are caught by the STRUCTURE-OBJECT test.
+    ((or array cons number character structure-object)
+     (values (psxhash key) nil))
+    (t
+     (eq-hash key))))
 
 (defun almost-primify (num)
   (declare (type index num))
index a58beb2..5ddbd21 100644 (file)
@@ -40,6 +40,7 @@
                             (and fixnum unsigned-byte))
                            (and fixnum unsigned-byte))
                 mix))
+(declaim (inline mix))
 (defun mix (x y)
   ;; FIXME: We wouldn't need the nasty (SAFETY 0) here if the compiler
   ;; were smarter about optimizing ASH. (Without the THE FIXNUM below,
     (structure-object (structure-object-psxhash key depthoid))
     (cons (list-psxhash key depthoid))
     (number (number-psxhash key))
-    (character (sxhash (char-upcase key)))
+    (character (char-code (char-upcase key)))
     (t (sxhash key))))
 
 (defun array-psxhash (key depthoid)
                   '(let ((result 572539))
                      (declare (type fixnum result))
                      (mixf result (length key))
-                     (dotimes (i (min depthoid (length key)))
+                     (dotimes (i (length key))
                        (declare (type fixnum i))
                        (mixf result
                              (psxhash (aref key i)
                                       (- depthoid 1 i))))
-                     result)))
-       ;; CMU can compile SIMPLE-ARRAY operations so much more efficiently
-       ;; than the general case that it's probably worth picking off the
-       ;; common special cases.
-       (typecase key
-         (simple-string
-          ;;(format t "~&SIMPLE-STRING special case~%")
-          (frob))
-         (simple-vector
-          ;;(format t "~&SIMPLE-VECTOR special case~%")
-          (frob))
-         (t (frob)))))
+                     result))
+                (make-dispatch (types)
+                  `(typecase key
+                     ,@(loop for type in types
+                             collect `(,type
+                                       (frob))))))
+       (make-dispatch (simple-base-string
+                       (simple-array character (*))
+                       simple-vector
+                       (simple-array (unsigned-byte 8) (*))
+                       (simple-array fixnum (*))
+                       t))))
     ;; Any other array can be hashed by working with its underlying
     ;; one-dimensional physical representation.
     (t
      (let ((result 60828))
        (declare (type fixnum result))
-       (dotimes (i (min depthoid (array-rank key)))
+       (dotimes (i (array-rank key))
          (mixf result (array-dimension key i)))
-       (dotimes (i (min depthoid (array-total-size key)))
+       (dotimes (i (array-total-size key))
          (mixf result
                (psxhash (row-major-aref key i)
                         (- depthoid 1 i))))
index dd90826..609eb10 100644 (file)
 (defknown hash-table-test (hash-table) symbol (foldable flushable))
 (defknown sxhash (t) (integer 0 #.sb!xc:most-positive-fixnum)
   (#-sb-xc-host foldable flushable))
+(defknown psxhash (t &optional t) (integer 0 #.sb!xc:most-positive-fixnum)
+  (#-sb-xc-host foldable flushable))
 \f
 ;;;; from the "Arrays" chapter
 
index 3106642..bc899fd 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.4.86"
+"1.0.4.87"