chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] Performance of write-char (and I/O in general)


From: Jeronimo Pellegrini
Subject: Re: [Chicken-users] Performance of write-char (and I/O in general)
Date: Thu, 25 Mar 2010 12:15:44 -0300
User-agent: Mutt/1.5.20 (2009-06-14)

I forgot to mention: this is with git master/HEAD
(4cbc9d250a5f2a60a4526ad1435c13a1d605cef4).

J.

On Thu, Mar 25, 2010 at 11:32:46AM -0300, Jeronimo Pellegrini wrote:
> Hello,
> 
> I recently noticed that reading numbers from a file was much
> slower from compiled Chicken using the read procedure than
> if I used fscanf directly from the FFI. (The thread is
> "Getting C file handle from port?").
> 
> Anyway, I understand that the standard read procedure will
> perform some checks (is it a port? what is the type of the
> object?) etc. So I made one for myself that just reads numbers
> and bails out if anything goes wrong.
> 
> But I'd expect writing to be faster, since there is no need for
> parsing. See this program:
> 
> /------- write-file.scm
> 
> (define write-char/ffi
>   (foreign-lambda* void ((char c)
>                          (scheme-object port))
>     "fprintf(C_port_file(port),\"%c\",c);"))
> 
> (define write-file/ffi
>     (lambda (port times)
>       (let ((a #\a))
>         (do ((i 0 (fx+ 1 i)))    
>             ((fx= i times))
>             (assert (char? a)) 
>             (assert (port? port))
>             (write-char/ffi #\a port)))))
> 
> (define write-file/write-char
>   (lambda (port times)
>     (do ((i 0 (fx+ 1 i)))
>       ((fx= i times))
>       (write-char #\a port))))
> 
> (let ((args (command-line-arguments)))
>   (let ((times (string->number (cadr args)))
>         (name  (car args)))
>     (call-with-output-file name
>       (lambda (port)
>         (time (write-file/write-char port times))))
>     (call-with-output-file name
>       (lambda (port)
>         (time (write-file/ffi port times))))))
> 
> \--------
> 
> $ csc -O5 write-file.scm
> 
> $ ./write-file tt 30000000
>    5.515 seconds elapsed
>    0.078 seconds in (major) GC
>        0 mutations
>        0 minor GCs
>      114 major GCs
>    0.575 seconds elapsed
>        0 seconds in (major) GC
>        0 mutations
>        0 minor GCs
>        0 major GCs
> 
> 
> OK, so maybe write-char is slow because it's verifying if the
> character was properly written.
> Let's see what happens if I also do this check in the FFI version:
> 
> (define write-char/ffi
>   (foreign-lambda* void ((char c)
>                          (scheme-object port))
>      "if (1 != fprintf(C_port_file(port),\"%c\",c)) exit(-1);" ))
> 
> Now the FFI version is much slower:
>    3.537 seconds elapsed
>        0 seconds in (major) GC
>        0 mutations
>        0 minor GCs
>        0 major GCs
> 
> Eh? A single if, and its test is just an integer comparison! What
> happened?
> 
> OK, so I'll dump fprintf and use a probably better suited function --
> fputc.
> 
> (define write-char/ffi
>   (foreign-lambda* void ((char c)
>                          (scheme-object port))
>      "if (EOF == fputc(c, C_port_file(port))) exit(-1);" ))
> 
> And HEY, it's fast!
> 
>    0.582 seconds elapsed
>        0 seconds in (major) GC
>        0 mutations
>        0 minor GCs
>        0 major GCs
> 
> (Actually, as fast as a C implementation I also made).
> 
> So -- what does write-char use internally? And why checking the
> return value of fprintf takes so much more time?
> 
> J.
> 
> 
> 
> _______________________________________________
> Chicken-users mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/chicken-users




reply via email to

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