0.8.8.23:
authorChristophe Rhodes <csr21@cam.ac.uk>
Wed, 10 Mar 2004 16:10:17 +0000 (16:10 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Wed, 10 Mar 2004 16:10:17 +0000 (16:10 +0000)
Better %SXHASH-SUBSTRING (patch Juho Snellman sbcl-devel 2004-03-09)
... frob comments a little
... make the same FLET workaround in %SXHASH-SIMPLE-SUBSTRING
... probably fasl-incompatible with 0.8.8.22, but I've already
changed the fasl version number once this cycle.  Let's
see if anyone complains :)
... 20% faster at compiling mk-defsystem on DB's iMac
(MORE SPEED!)

NEWS
src/code/target-sxhash.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 1d40778..0b1ee32 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2327,6 +2327,9 @@ changes in sbcl-0.8.9 relative to sbcl-0.8.8:
     WARNINGs, not just STYLE-WARNINGs, on the assumption that this is
     more often programmer error than deliberate exploitation of undefined
     behaviour.
+  * optimization: the hash algorithm for strings has changed to one
+    that is less vulnerable to spurious collisions.  (thanks to Juho
+    Snellman)
   * optimization: implemented multiplication as a modular
     (UNSIGNED-BYTE 32) operation on the PPC backend.
   * fixed some bugs revealed by Paul Dietz' test suite:
index 571b9c1..99e0830 100644 (file)
 \f
 ;;;; hashing strings
 ;;;;
-;;;; Note that this operation is used in compiler symbol table lookups, so we'd
-;;;; like it to be fast.
+;;;; Note that this operation is used in compiler symbol table
+;;;; lookups, so we'd like it to be fast.
+;;;;
+;;;; As of 2004-03-10, we implement the one-at-a-time algorithm
+;;;; designed by Bob Jenkins (see
+;;;; <http://burtleburtle.net/bob/hash/doobs.html> for some more
+;;;; information).
 
 #!-sb-fluid (declaim (inline %sxhash-substring))
 (defun %sxhash-substring (string &optional (count (length string)))
   ;; FIXME: As in MIX above, we wouldn't need (SAFETY 0) here if the
-  ;; cross-compiler were smarter about ASH, but we need it for sbcl-0.5.0m.
+  ;; cross-compiler were smarter about ASH, but we need it for
+  ;; sbcl-0.5.0m.  (probably no longer true?  We might need SAFETY 0
+  ;; to elide some type checks, but then again if this is inlined in
+  ;; all the critical places, we might not -- CSR, 2004-03-10)
   (declare (optimize (speed 3) (safety 0)))
   (declare (type string string))
   (declare (type index count))
-  (let ((result 408967240))
-    (declare (type fixnum result))
+  (let ((result 0))
+    (declare (type (unsigned-byte 32) result))    
     (unless (typep string '(vector nil))
       (dotimes (i count)
        (declare (type index i))
-       (mixf result
-             (the fixnum
-               (ash (char-code (aref string i)) 5)))))
-    result))
+       (setf result
+             (ldb (byte 32 0)
+                  (+ result (char-code (aref string i)))))
+       (setf result
+             (ldb (byte 32 0)
+                  (+ result (ash result 10))))
+       (setf result
+             (logxor result (ash result -6)))))
+    (setf result
+         (ldb (byte 32 0)
+              (+ result (ash result 3))))
+    (setf result
+         (logxor result (ash result -11)))
+    (setf result
+         (ldb (byte 32 0)
+              (logxor result (ash result 15))))
+    (logand result most-positive-fixnum)))
 ;;; test:
 ;;;   (let ((ht (make-hash-table :test 'equal)))
 ;;;     (do-all-symbols (symbol)
 (defun %sxhash-simple-string (x)
   (declare (optimize speed))
   (declare (type simple-string x))
-  (%sxhash-substring x))
+  ;; KLUDGE: this FLET is a workaround (suggested by APD) for presence
+  ;; of let conversion in the cross compiler, which otherwise causes
+  ;; strongly suboptimal register allocation.
+  (flet ((trick (x)
+           (%sxhash-substring x)))
+    (declare (notinline trick))
+    (trick x)))
 
 (defun %sxhash-simple-substring (x count)
   (declare (optimize speed))
   (declare (type simple-string x))
   (declare (type index count))
-  (%sxhash-substring x count))
+  ;; see comment in %SXHASH-SIMPLE-STRING
+  (flet ((trick (x count)
+          (%sxhash-substring x count)))
+    (declare (notinline trick))
+    (trick x count)))
 \f
 ;;;; the SXHASH function
 
index 7dc6b0c..85c5a2c 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".)
-"0.8.8.22"
+"0.8.8.23"