; .EnTete "Le←Lisp version 15.2" " " "Tests of the Hash-Table Facility" ; .Titre "Tests of the Hash-Table Facility" ; .Auteur "Je'ro↑me Chailloux" ; .Centre "$Header: testhash.ll,v 1.8 89/01/11 19:21:09 kuczynsk Exp $" ;;; How to run this test : ;;; ;;; % complice ;;; ↑Ahash ;;; ↑Ltesthash ;;; (compile-all-in-core) ;;; (setq #:hash-table:debug t) ;;; (:test) ;;; (:subexpr) ;;; ;;; (unless (featurep 'format) (loadmodule 'format)) ; .Section "The predicat which tests if a Lisp object is circular or shared" (defun :is-circular-or-shared-p (:x) (let ((:seen)) (tag :finish (:is-circular-aux :x) ()))) (defvar :elem) (defun :is-circular-aux (:x) (cond ((memq :x :seen) (exit :finish t)) ((consp :x) (newl :seen :x) (when (neq (car :x) 'QUOTE) (:is-circular-aux (car :x)) (:is-circular-aux (cdr :x)))) ((vectorp :x) (newl :seen :x) (mapvector (lambda (:elem) (when (boundp ':elem) (:is-circular-aux :elem))) :x)) (t ()))) ; .Section "Statistics & Tests" (defvar :ht ()) ; the recipient of the created hash-tables. (defun :test :list-of-tests ;; the main test function (in the package USER) (when (or (null :list-of-tests) (memq 'FIX :list-of-tests)) (:run0 'EQ "regular fixnums with EQ" (:makenb 5000) '(10 20 30 40 50 100 200 300 400 500 1000 1500 2000 2500 3000) '(1000 500 300 150 90 50 5 3 2 2 1 1 1 1 1))) (when (or (null :list-of-tests) (memq 'SYMBOL :list-of-tests)) (:run0 'EQ "system symbols with EQ" (:makelen 2000) '(10 20 30 40 50 100 200 300 400 500 1000 1500 2000) '(1000 500 300 150 100 10 5 3 2 2 1 1 1))) (when (or (null :list-of-tests) (memq 'SYMBOL :list-of-tests)) (:run0 'EQUAL "system symbols with EQUAL" (:makelen 2000) '(10 20 30 40 50 100 200 300 400 500 1000 1500 2000) '(1000 500 300 150 100 10 5 3 2 2 1 1 1))) (when (or (null :list-of-tests) (memq 'STRING :list-of-tests)) (:run0 'EQUAL "system strings with EQUAL" (:makestrg 2000) '(10 20 30 40 50 100 200 300 400 500 1000 1500 2000) '(1000 500 300 150 100 10 5 3 2 2 1 1 1))) (when (or (null :list-of-tests) (memq 'VECTOR :list-of-tests)) (:run0 'EQUAL "system vectors with EQUAL" (:makevect 150) '(10 20 30 40 50 100) '(1000 500 300 150 100 10 ))) ) (defun :makelen (size) ;; creates a list of "size" symbols, all different (let ((:ln (oblist))) (setq :ln (delete '←undef← :ln)) (firstn size :ln))) (defun :makenb (size) ;; creates a list of "size" fixnums, all different (let ((:ln (makelist size ()))) (let ((:ln :ln) (:i 0)) (while :ln (rplaca :ln (setq :i (add1 :i))) (nextl :ln))) :ln)) (defun :makestrg (size) ;; creates a list of "size" strings, all different (let ((:ln (makelist size ()))) (let ((:lnn :ln)) (tag fin (#:system:mapallstring (lambda (x) (when (and (null (member x :ln)) ; remove all the system strings!! (neq (slen x) 256)) (rplaca :lnn x) (nextl :lnn) (when (null :lnn) (exit fin))))))) (setq :gla :ln) :ln)) (defun :makevect (size) ;; creates a list of "size" vectors, ;; all different without any circular vectors. ;; the hash-tables objects are excluded because they can ;; be modified any time. (let ((:ln (makelist size ())) (:to-remove (let ((l)) (#:system:mapallvector (lambda (x) (when (hash-table-p x) (newl l x) (newl l (hash-table-values x))))) l))) ; remove the TABCHAN vector (which is mutable!) (let ((x (channel t))) (#:system:mapallvector (lambda (v) (when (equal x v) (newl :to-remove v))))) (setq :gla :to-remove) (let ((:lnn :ln)) (tag fin (#:system:mapallvector (lambda (x) (when (and (null (memq x :to-remove)) (null (member x :ln)) (null (:is-circular-or-shared-p x))) (rplaca :lnn x) (setq :lnn (cdr :lnn)) (when (null :lnn) (exit fin))))))) (setq :gln :ln) :ln)) (defvar :in-test-p ()) (defun gcalarm () (when :in-test-p (print "GC during the HASH test" (gcinfo)))) (defun :run0 (type msg listobj listlen listsfact) (print) (print "==================== " msg " ====================") (mapc (lambda (len sfact) (setq :ht (if (eq type 'EQ) (make-hash-table-eq) (make-hash-table-equal))) (print) (print "===== " msg " length=" len " scaling=" sfact) (:run1 (firstn len listobj) sfact 'EQ) (#:hash-table:print-stat "resulting hash-table" :ht)) listlen listsfact)) (defun :run1 (:list-of-objects :scaling-factor :type) (let* ((:runtime 0.0) (:length-of-list-of-objects (length :list-of-objects)) (:equivalent-A-list (let ((:index 0)) (mapcar (lambda (:elem) (cons :elem (setq :index (add1 :index)))) :list-of-objects)))) (gc) (let ((:in-test-p t)) (print) (print "Time to hash the list of objects") (setq :runtime (runtime)) (let ((:index 0)) (mapc (lambda (:elem) (setf (gethash :elem :ht) (setq :index (add :index 1)))) :list-of-objects)) (setq :runtime (- (runtime) :runtime)) (print "Time in sec = " :runtime) (print "Average in microsec = " (/ (* 1000000. :runtime) :length-of-list-of-objects))) (let ((:in-test-p t)) (print) (print "Time to retrieve and check all the objects with an HASH-TABLE") (setq :runtime (runtime)) (repeat :scaling-factor (let ((:index 0)) (mapc (lambda (:elem) (when (neq (gethash :elem :ht) (setq :index (add1 :index))) (:printerror "Hash-Table BUG" (list :elem :ht :index)))) :list-of-objects))) (setq :runtime (- (runtime) :runtime)) (print "Time in sec = " :runtime) (print "Average in microsec = " (/ (/ (* 1000000. :runtime) :length-of-list-of-objects) :scaling-factor))) (let ((:in-test-p t)) (print) (print "Time to retrieve and check all the objects with an A-List") (if (eq :type 'EQ) (progn (setq :runtime (runtime)) (repeat :scaling-factor (let ((:index 0)) (mapc (lambda (:elem) (when (neq (cassq :elem :equivalent-A-list) (setq :index (add1 :index))) (:printerror "A-List EQ BUG" :elem))) :list-of-objects))) (setq :runtime (- (runtime) :runtime))) (progn (setq :runtime (runtime)) (repeat :scaling-factor (let ((:index 0)) (mapc (lambda (:elem) (when (neq (cassoc :elem :equivalent-A-list) (setq :index (add1 :index))) (:printerror "A-List EQUAL BUG" :elem))) :list-of-objects))) (setq :runtime (- (runtime) :runtime)))) (print "Time in sec = " :runtime) (print "Average in microsec = " (/ (/ (* 1000000. :runtime) :length-of-list-of-objects) :scaling-factor)))) (when #:hash-table:debug (mapvector (lambda (x) (when (gt (length x) 10) (with ((lmargin 10)) (print (length x) "====") (mapc 'print x)) (print))) (hash-table-values :ht))) ))) (defun :printerror (msg larg) (print "***** PRINTERROR " msg " larg=" larg)) ; .Section "Search the common sub-expressions" (defun :subexpr () (:subfiles '( "../llobj/complice.lo")) (:subfiles '( "../llib/llcp.ll")) (:subfiles '( "../llib/llcp.ll" "../llib/lap68k.ll"))) (defun :subfiles (files) (let ((list-of-objects) (read-object) (number-of-objects 0) (runt) (ht (make-hash-table-equal))) (print) (print "======= Common Sub Expressions with the files : " files) (gc) (setq runt (runtime)) (mapc (lambda (file) (dynamic-let ((#:sys-package: colon #:sys-package:colon)) (with ((inchan (openi file))) (untilexit eof (setq read-object (read)) (when (and (consp read-object) (memq (car read-object) '(unless defvar setq))) (eval read-object)) (newl list-of-objects read-object))))) files) (setq runt (- (runtime) runt)) (print "Time to read the files " runt) (gc) (setq runt (runtime)) (:subexpr-aux list-of-objects ht) (setq runt (- (runtime) runt)) (print "Time to hash the files " runt) (maphash (lambda (key value) (setq number-of-objects (add number-of-objects value))) ht) (print "number of objects " number-of-objects) (print "search by element " (/ runt number-of-objects)) (#:hash-table:print-stat "common sub expr" ht) (when #:hash-table:debug (maphash (lambda (key value) (when (neq value 1) (print value "++++" key))) ht) (mapvector (lambda (x) (when (gt (length x) 10) (print (length x) "====") (with ((lmargin 10)) (mapc 'print x)))) (hash-table-values ht))) (gc) (setq runt (runtime)) (dynamic-let ((:seen)) (:subexpr-alist list-of-objects) (setq runt (- (runtime) runt)) (print "Time to a-list the file " runt) (print "search by element " (/ runt number-of-objects)) (print "Length of the A-list " (length :seen))))) (defun :subexpr-alist (l) (when (consp l) (let ((i (assoc l :seen))) (if (consp i) (setf (cdr i) (+ (cdr i) 1)) (newl :seen (cons l 1)))) (mapc ':subexpr-alist l))) (defun :subexpr-aux (list-of-objects ht) (if (atom list-of-objects) ht (progn (inchash list-of-objects ht 1 1) (while (consp list-of-objects) (when (consp (car list-of-objects)) (:subexpr-aux (car list-of-objects) ht)) (setq list-of-objects (cdr list-of-objects))) ht))) (progn (print "(:test) to performs meters") (print "(:subexpr) or (:subexpr <files*>)") (print "to compute the common subexpressions")) (unless (featurep 'testcomm) (libload testcomm)) (testfn ()) (test-serie "[Hash-tables tests]") (setq ht (make-hash-table-eq) v ()) () (puthash 'k1 ht 1) 1 (gethash 'k1 ht) 1 (gethash 'k2 ht) () (gethash 'k2 ht 'def) def () ()