Compiling a program to native code with mzc can provide significant speedups compared to interpreting byte codes (or running the program directly from source code) for certain kinds of programs. The speedup from native code compilation is typically due to two optimizations:
(letrec ([odd (lambda (x)
(if (zero? x)
#f
(even (sub1 x))))]
[even (lambda (x)
(if (zero? x)
(odd (sub1 x))))])
(odd 40000))
mzc can detect the odd-even loop and produce native
code that runs twice as fast as byte code interpretation. In contrast,
given a similar program using top-level definitions,
(define (odd x) ...) (define (even x) ...)the compiler cannot assume an odd-even loop, because the global variables odd and even can be redefined at any time. Note that defined variables in a unit module are lexically scoped like letrec variables, and unit definitions therefore permit loop optimizations.
(define oe-unit
(unit (import) (export) ; import nothing, export nothing
(letrec ([odd (lambda (x)
(if (zero? x)
#f
(even (sub1 x))))]
[even (lambda (x)
(if (zero? x)
(odd (sub1 x))))])
(odd 40000))))
(invoke-unit oe-unit) ; run the program
Native code compilation rarely produces significant speedup for programs that are not loop-intensive, programs that are heavily object-oriented, programs that are allocation-intensive, or programs that exploit built-in procedures (e.g., list operations, regular expression matching, or file manipulations) to perform most of the program's work.