Racket programs and expressions are compiled automatically and on-the-fly. The raco make tool (see raco make: Compiling Source to Bytecode) can compile a Racket module to a compiled ".zo" file, but that kind of ahead-to-time compilation simply allows a program takes to start more quickly, and it does not affect the performance of a Racket program.
All Racket variants suppose a machine-independent compilation mode, which generates compiled ".zo" files that work with all Racket variants on all platforms. To select machine-independent compilation mode, set the current-compile-target-machine parameter to #f or supplying the --compile-any/-M flag on startup. See current-compile-target-machine for more information.
Other compilation modes depend on the Racket variant (see Implementations).
The BC implementation of Racket supports two compilation modes: bytecode and machine-independent. The bytecode format is also machine-independent in the sense that it works the same on all operating systems for the BC implementation of Racket, but it does not work with the CS implementation of Racket.
Bytecode is further compiled to machine code at run time, unless the JIT compiler is disabled. See eval-jit-enabled.
The CS implementation of Racket supports several compilation modes: machine code, machine-independent, interpreted, and JIT. Machine code is the primary mode, and the machine-independent mode is the same as for BC. Interpreted mode uses an interpreter at the level of core linklet forms with no compilation. JIT mode triggers compilation of individual function forms on demand.
The default mode is a hybrid of machine-code and interpreter modes, where interpreter mode is used only for the outer contour of an especially large linklet, and machine-code mode is used for functions that are small enough within that outer contour. “Small enough” is determined by the PLT_CS_COMPILE_LIMIT environment variable, and the default value of 10000 means that most Racket modules have no interpreted component.
JIT compilation mode is used only if the PLT_CS_JIT environment variable is set on startup, otherwise pure interpreter mode is used only if PLT_CS_INTERP is set on startup, and the default hybrid machine code and interpreter mode is used if PLT_CS_MACH is set and PLT_CS_JIT is not set or if none of those environment variables is set. A module compiled in any mode can be loaded into the CS variant of Racket independent of the current compilation mode.
The PLT_CS_DEBUG environment variable, as described in Debugging, affects only compilation in machine-code mode. Generated machine code is much larger when PLT_CS_DEBUG is enabled, but performance is not otherwise affected.
When the PLT_LINKLET_SHOW environment variable is set on startup, the Racket process’s standard output shows intermediate compiled forms whenever a Racket form is compiled. For all Racket variants, the output shows one or more linklets that are generated from the original Racket form.
For the CS implementation of Racket, a “schemified” version of the linklet is also shown as the translation of the linklet form to a Chez Scheme procedure form. The following environment variables imply PLT_LINKLET_SHOW and show additional intermediate compiled forms or adjust the way forms are displayed:
When the PLT_LINKLET_TIMES environment variable is set on startup, then Racket prints cumulative timing information about compilation and evaluation times on exit. When the PLT_EXPANDER_TIMES environment variable is set, information about macro-expansion time is printed on exit.