Speed benefits of submodules?

Suppose I have two Racket files/modules:

;; one.rkt

#lang racket

(provide a b)
(define foo 'simple-value)
(define bar (make-bytes 100000 65))
;; two.rkt

#lang racket

(module small racket
  (provide foo)
  (define foo 'simple-value))

(provide bar)
(define bar (make-bytes 100000 65))

Is it any faster to (require (submod "two.rkt" small)) than to (require "one.rkt") if all I want is foo? That is, is there any performance benefit (or penalty) at runtime in using submodules, even though they are compiled “inside” their containing modules?

1 Like


Running a module does not necessarily run its submodules. In the above example, running "park.rkt" runs its submodule zoo only because the "park.rkt" module requires the zoo submodule. Otherwise, a module and each of its submodules can be run independently. Furthermore, if "park.rkt" is compiled to a bytecode file (via raco make), then the code for "park.rkt" or the code for zoo can be loaded independently.

Submodules can be nested within submodules, and a submodule can be referenced directly by a module other than its enclosing module by using a submodule path.

I haven't done any benchmarks/timings whether there is any difference in practice.

1 Like

Assuming you include startup/load time as "runtime": I'd expect not requiring "one.rkt" to be better, much like using #lang racket/base instead of #lang racket. Less work is done and less memory is used.

In addition to avoiding the initialization of bar that you don't need from "one.rkt", you're avoiding all of "one.rkt"'s transitive requires and their module-level definitions/expressions.

And if someday someone adds more module-level definitions or requires to "one.rkt", you're insulated from that in "two.rkt".

Having said all that, like @simonls I'm not sure the practical/measurable performance difference?

Also, this seems like it's really about the cost of requires, not the benefit of submodules; you'd avoid the same cost whether foo was defined in a submodule or in the top file module? (Using a submodule adds an extra configure-runtime cost -- but I think it's very, very tiny for most langs?)

Another idea would be to move the definition of foo to a new "foo.rkt" file that's required by both "one.rkt" and "two.rkt" -- motivated not so much by performance, but as an organizing principle??

The question arises from

Thanks — the question arises because of a #lang I’m working on that will automatically provide some values. One of the values is likely to be smaller and more frequently accessed than the others. So I’m wondering if my lang should put that value in its own submodule. It’s not something the user of the #lang would have any control over.

I could (and probably will) do all the benchmarking, but I still want to know whether there is any expected benefit to doing this, that is, . (And yes I do include load time!)