[racket] returning self as sync result with struct prop:evt and wrap-evt
At Wed, 27 Jun 2012 18:20:45 -0400, Neil Van Dyke wrote:
> Question: If I put a "log-debug" into that "(lambda (self) ...)" proc,
> looks like the proc is applied every time i call "sync". If the
> "log-debug" isn't in there, is the overhead of applying that proc and
> "wrap-evt" each time I call "sync" practically zero, or would I possibly
> get better I/O performance with the "letrec" and calling "wrap-evt" only
> once?
I don't know. Lets try a rough measurement...
Base port is a bytes port with 1,000,000 bytes, loop to eof,
times in msec:
just read sync then read
direct 45 (gc: 0) 325 (gc: 19)
letrec 51 (gc: 0) 834 (gc: 12)
self 51 (gc: 0) 1297 (gc: 17)
So, yes, counting just the `sync' overhead, it's roughly 50% slower in
to use `(lambda (self) ...)', though apparently with little extra GC.
In more absolute terms, the overhead is on the order of 1 msec or about
10x the cost to read a byte out of a port. Whether that's "practically
zero" depends on what you're doing with each byte.
----------------------------------------
go.rkt
----------------------------------------
#lang racket
(provide go)
(define N 1000000)
(define (mk-in) (open-input-bytes (make-bytes N 0)))
(define (go mk my-struct-read)
(define s (mk (mk-in)))
;; just read:
(time
(let loop ()
(let ((v (my-struct-read s)))
(unless (eof-object? v)
(loop)))))
(define s2 (mk (mk-in)))
;; sync & read::
(time
(let loop ()
(let ((my-evt-result (sync s2)))
(let ((v (my-struct-read s2)))
(unless (eof-object? v)
(loop)))))))
----------------------------------------
direct.rkt
----------------------------------------
#lang racket/base
(require "go.rkt")
(go values read-byte)
----------------------------------------
letrec.rkt
----------------------------------------
#lang racket/base
(require "go.rkt")
(struct my-struct (my-wrapped-evt my-wrapping-evt)
#:property prop:evt (struct-field-index my-wrapping-evt))
(define (my-struct* my-wrapped-evt)
(letrec ((my-wrapping-evt (wrap-evt my-wrapped-evt
(lambda (ignored-wrapped-evt)
s)))
(s (my-struct my-wrapped-evt
my-wrapping-evt)))
s))
(define (my-struct-read s)
(read-byte (my-struct-my-wrapped-evt s)))
(go my-struct* my-struct-read)
----------------------------------------
self.rkt
----------------------------------------
#lang racket/base
(require "go.rkt")
(struct my-struct (my-wrapped-evt)
#:property prop:evt (lambda (self)
(wrap-evt (my-struct-my-wrapped-evt self)
(lambda (ignored)
self))))
(define (my-struct-read s)
(read-byte (my-struct-my-wrapped-evt s)))
(go my-struct my-struct-read)