chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] pathname-normalize


From: Kon Lovett
Subject: Re: [Chicken-users] pathname-normalize
Date: Mon, 1 May 2006 07:16:44 -0700

On Apr 30, 2006, at 10:45 PM, Reed Sheridan wrote:

From: Kon Lovett <address@hidden>
Subject: Re: [Chicken-users] Re: photo album in chicken
To: chicken <address@hidden>
Message-ID: < address@hidden>
Content-Type: text/plain; charset="us-ascii"

<snip>
That looks good, except for one thing: reverse! is from srfi-1.  Use reverse instead.  Also, the

I know. I'm just working on larger pkgs lately & tend to have srfi-1 around all the time. For Chicken library code you are correct.

implementation of absolute-path? has a bug.  It returns #t for a pathname starting with windows-style drive letters, but in Unix, A:/foo is a perfectly valid relative pathname.  I'm not sure how to conditionalize Chicken code for Windows, or I'd fix this.

Thanks, I forgot. I have to look into Windows vs. Unix anyway.

----

Not to beat a dead horse but I thought people might be interested. I timed the performance of 10000 runs of 'pathname-normalize' using the 2 impls below. (Ignore the reverse! & absolute-pathname for now.)

(define (pathname-normalize1 path)
(let loop ([rparts (reverse! (string-split path "/"))] [oparts '()])
(if (null? rparts)
(string-join (or (and (absolute-pathname? path) (cons "" oparts)) oparts) "/")
(let ([cur (car rparts)] [nxt (cdr rparts)])
(cond
[(string=? "." cur)
(loop nxt oparts)]
[(and (not (null? nxt)) (string=? ".." cur))
(loop (or (and (not (string=? ".." (car nxt))) (cdr nxt)) nxt) oparts)]
[else
(loop nxt oparts)])))))

(define (pathname-normalize2 path)
  (let loop ([rparts (reverse! (string-split path "/"))] [skip 0] [acc '()])
    (match rparts
      (() (string-join (or (and (absolute-pathname? path) (cons "" acc)) acc) "/"))
      (("." . more) (loop more skip acc))
      ((".." . more) (loop more (add1 skip) acc))
      ((path-part . more)
         (if (zero? skip)
   (loop more 0 (cons path-part acc))
   (loop more (sub1 skip) acc))))))

Test path: "asdf/../../asdf"

Interpreter:

pathname-normalize1:
   0.917 seconds elapsed
     0.1 seconds in (major) GC
  155290 mutations
      16 minor GCs
      40 major GCs

pathname-normalize2:
   1.981 seconds elapsed
   0.284 seconds in (major) GC
  406856 mutations
      15 minor GCs
     109 major GCs

Compiler (fixnum):

pathname-normalize1:
   0.237 seconds elapsed
   0.012 seconds in (major) GC
   90000 mutations
      59 minor GCs
       7 major GCs

pathname-normalize2:
   0.271 seconds elapsed
   0.016 seconds in (major) GC
   90000 mutations
     226 minor GCs
       9 major GCs

A recursion is more expensive than a test, so this makes sense. 

Best Wishes,
Kon


Reed Sheridan


_______________________________________________
Chicken-users mailing list


reply via email to

[Prev in Thread] Current Thread [Next in Thread]