~ chicken-core (chicken-5) 2df56df8a5a48fc4eb1a6094f7ce44f2192c963e


commit 2df56df8a5a48fc4eb1a6094f7ce44f2192c963e
Author:     Mario Domenech Goulart <mario.goulart@gmail.com>
AuthorDate: Tue Jun 2 22:08:17 2015 -0300
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Fri Jun 12 16:32:21 2015 +1200

    posix-common: find-files: use `directory' instead of `glob'
    
    Using `directory' instead of `glob' gives a nice speed boost:
    
    With `glob':
    
    (time (find-files "."))
    2.1s CPU time, 0.164s GC time (major), 2759998/21115 mutations (total/tracked), 4/15016 GCs (major/minor)
    
    With `directory`:
    
    (time (find-files "."))
    0.58s CPU time, 0.092s GC time (major), 220194/12135 mutations (total/tracked), 3/2633 GCs (major/minor)
    
    Timings for `(find-files ".")' on a directory containing the Linux
    source code.
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>

diff --git a/posix-common.scm b/posix-common.scm
index 00601671..8b3e4e5f 100644
--- a/posix-common.scm
+++ b/posix-common.scm
@@ -495,37 +495,40 @@ EOF
 
 ;;; Find matching files:
 
-(define ##sys#find-files
-  (lambda (dir pred action id limit follow dot loc)
-    (##sys#check-string dir loc)
-    (let* ((depth 0)
-	   (lproc
-	    (cond ((not limit) (lambda _ #t))
-		  ((fixnum? limit) (lambda _ (fx< depth limit)))
-		  (else limit) ) )
-	   (pproc
-	    (if (procedure? pred)
-		pred
-		(let ((pred (irregex pred))) ; force compilation
-		  (lambda (x) (irregex-match pred x))) ) ) )
-      (let loop ((fs (glob (make-pathname dir (if dot "?*" "*"))))
-		 (r id) )
-	(if (null? fs)
-	    r
-	    (let ((f (##sys#slot fs 0))
-		  (rest (##sys#slot fs 1)) )
-	      (cond ((directory? f)
-		     (cond ((member (pathname-file f) '("." "..")) (loop rest r))
-			   ((and (symbolic-link? f) (not follow))
-			    (loop rest (if (pproc f) (action f r) r)))
-			   ((lproc f)
-			    (loop rest
-				  (fluid-let ((depth (fx+ depth 1)))
-				    (loop (glob (make-pathname f (if dot "?*" "*")))
-					  (if (pproc f) (action f r) r)) ) ) )
-			   (else (loop rest (if (pproc f) (action f r) r))) ) )
-		    ((pproc f) (loop rest (action f r)))
-		    (else (loop rest r)) ) ) ) ) ) ) )
+(define (##sys#find-files dir pred action id limit follow dot loc)
+  (##sys#check-string dir loc)
+  (let* ((depth 0)
+         (lproc
+          (cond ((not limit) (lambda _ #t))
+                ((fixnum? limit) (lambda _ (fx< depth limit)))
+                (else limit) ) )
+         (pproc
+          (if (procedure? pred)
+              pred
+              (let ((pred (irregex pred))) ; force compilation
+                (lambda (x) (irregex-match pred x))))))
+    (let loop ((dir dir)
+               (fs (directory dir dot))
+               (r id))
+      (if (null? fs)
+          r
+          (let* ((filename (##sys#slot fs 0))
+                 (f (make-pathname dir filename))
+                 (rest (##sys#slot fs 1)))
+            (cond ((directory? f)
+                   (cond ((member filename '("." "..")) (loop dir rest r))
+                         ((and (symbolic-link? f) (not follow))
+                          (loop dir rest (if (pproc f) (action f r) r)))
+                         ((lproc f)
+                          (loop dir
+                                rest
+                                (fluid-let ((depth (fx+ depth 1)))
+                                  (loop f
+                                        (directory f dot)
+                                        (if (pproc f) (action f r) r)))))
+                         (else (loop dir rest (if (pproc f) (action f r) r)))))
+                  ((pproc f) (loop dir rest (action f r)))
+                  (else (loop dir rest r))))))))
 
 (define (find-files dir #!key (test (lambda _ #t))
 			      (action (lambda (x y) (cons x y)))
Trap