[plt-dev] Re: Speed up check-syntax
[Moving to plt-dev.]
On Nov 9, Robby Findler wrote:
>
> I find such behavior annoying in my OS and expect it would be the
> same in DrScheme. Things will be sluggish while it is loading.
>
> Nevertheless, I will try this if the parallelism stuff doesn't pan
> out.
1. I find the delay-on-first-syncheck especially annoying in class. I
always start a new drscheme at the beginning of the class, which
means that I'm guaranteed to get the annoying delay. (And it's a
classic case of unjustified delay, since drscheme will sit there
for many minutes doing nothing before I get to use it.) It's at a
level where I hesitate to use it -- and on some occasions I
pre-arrange myself so that I click it while I speak to mask out the
delay. (Being able to do such things is something that I had to
learn as a stutterer...)
2. BTW, the status-line message is not showing at all on linux. I
never knew that there was supposed to be such a message. (I almost
never run it on my laptop.)
3. IMO, the issue will not be completely resolved with multiple
cores. What if my other core is busy doing something else? What
about school machines that can be very outdated? What about IO
delays, since this does involve mostly IO?
4. The usual way to do these things is to have it loaded when it is
idle (exactly what Stephen said) -- but then don't just start to
load it so everything becomes slow, just do that in little
execution chunks which are done only if the system is still
otherwise idle. I think that MzScheme could use some more
functionality in this area -- a nice feature to have would be a way
for a thread to change its priority where this can also be a "run
me only when otherwise idle" (it would be especially nice to have a
hierarchy of these: "run me when otherwise idle including 1st-level
idle-priority threads, and give me only 20% running time").
5. Fantasies aside, I think that it is possible to do a reasonable job
for this given the current tools. The code below looks to me like
it should work fine. It runs a given thunk in the background while
drscheme is idle, and using little cpu time so there's no alarming
cpu load. The returned result is a thunk that returns the computed
value -- waiting for it (while giving it 100% cpu) if it isn't
ready yet.
6. To try it, I basically changed "syncheck.ss" with this definition:
(define get-xref
(run-lazily (lambda ()
(with-handlers ([exn? (lambda (_) #f)])
(load-collections-xref)))))
I've tried it in DrScheme (on my Windows laptop, so the delay is
more noticeable), and it looks like it works fine. No need for
multicore support...
7. Maybe this would be a good addition to `scheme/promise'.
;; Run `thunk' when idle, slicing the time to `slice'-second frames,
;; using only `use' seconds from each frame. Return a thunk that
;; returns the result of the computation, giving it full cpu if it's not
;; ready yet.
(define (run-lazily thunk #:slice [slice 0.3] #:use [use 0.05])
(define idle-evt (system-idle-evt))
(define force-sema (make-semaphore 0))
(define results #f)
(define (work)
(with-handlers ([void (lambda (e) (set! results (cons raise e)))])
(set! results (cons values (call-with-values thunk list)))))
(define (start)
(sync idle-evt)
(let ([worker (parameterize ([current-thread-group (make-thread-group)])
(thread work))])
(thread-suspend worker)
(let loop ()
;; rest, then wait for idle time, then resume working
(if (eq? (begin0 (or (sync/timeout (- slice use) force-sema)
(sync idle-evt force-sema))
(thread-resume worker))
force-sema)
;; forced during one of these => let it run to completion
(thread-wait worker)
;; not forced
(unless (sync/timeout use worker) (thread-suspend worker) (loop))))))
(define main-thread
(parameterize ([current-thread-group (make-thread-group)])
(thread start)))
(lambda ()
(unless (thread-dead? main-thread)
(semaphore-post force-sema)
(thread-wait main-thread))
(apply (car results) (cdr results))))
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!