[racket] improving speed of namespace attachment/requiring?

From: Danny Yoo (dyoo at hashcollision.org)
Date: Wed Feb 27 18:05:25 EST 2013

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!

Posted on the users mailing list.