[racket] improving speed of namespace attachment/requiring?
Hi everyone,
I'm working on making Whalesong be the evaluator for the WeScheme
environment. One problem I'm running into is the speed of REPL
compilation. I'm compiling on the server side, and I want the
compiler to be stateless, so I create a clean namespace per individual
interaction.
I'm doing something like this to create such namespaces:
###################################
#lang racket/base
(define this-namespace (make-base-empty-namespace))
(define (make-repl-namespace [module-path 'racket/base])
(parameterize ([current-namespace this-namespace])
(dynamic-require module-path #f))
(make-empty-namespace)
(define ns (make-empty-namespace))
(parameterize ([current-namespace ns])
(namespace-attach-module this-namespace module-path)
(namespace-require module-path))
ns)
###################################
I create a single this-namespace to hold the instantiation of my base
language module, and then inject it into a fresh namespace I construct
per repl interaction. That way, I instantiate my language module just
once, rather than per interaction. I note, though, that if I do this,
the cost of attaching and requiring the module can still be a little
expensive, depending on the language namespace I want to construct.
For example, if I execute the following:
###################################
(for ([i 10])
(time (parameterize ([current-namespace (make-repl-namespace
'lang/htdp-beginner)])
(let ()
(compile
'(* x 3))))))
###################################
then I observe the following on the Racket console:
######################
cpu time: 256 real time: 275 gc time: 69
cpu time: 22 real time: 23 gc time: 0
cpu time: 63 real time: 65 gc time: 34
cpu time: 21 real time: 22 gc time: 0
cpu time: 20 real time: 20 gc time: 0
cpu time: 38 real time: 41 gc time: 11
cpu time: 23 real time: 23 gc time: 0
cpu time: 43 real time: 44 gc time: 21
cpu time: 24 real time: 26 gc time: 0
cpu time: 17 real time: 17 gc time: 0
######################
This isn't so bad, on my laptop, but I expect the times to double at
least when I deploy to my slower Amazon EC2 servers. Can I do better
here? If I switch the language here to 'racket/base, then it's a lot
faster: why?
I still have some tricks I can play (like memoizing the compiler).
But anything I can do to keep the compilation cost down would be
greatly appreciated. Thanks!