Add a section on performance debugging to the TR guide.

original commit: f9205665e4e1af4808e3080592968d3b43500383
This commit is contained in:
Vincent St-Amour 2011-06-17 17:32:01 -04:00
parent 77e9234c06
commit d54c43282b

View File

@ -1,11 +1,9 @@
#lang scribble/manual
@begin[(require (for-label (only-meta-in 0 typed/racket)) scribble/eval
@begin[(require (for-label (only-meta-in 0 typed/racket))
scribble/eval racket/sandbox
"../utils.rkt" (only-in "quick.scrbl" typed-mod))]
@(define the-eval (make-base-eval))
@(the-eval '(require typed/racket))
@title[#:tag "optimization"]{Optimization in Typed Racket}
Typed Racket provides a type-driven optimizer that rewrites well-typed
@ -159,3 +157,67 @@ In many such cases, however, @seclink[#:doc '(lib
"scribblings/guide/guide.scrbl") "define-struct"]{structs} are
preferable to vectors. Typed Racket can optimize struct access in all
cases.
@subsection{Performance Debugging}
Typed Racket provides performance debugging support to help you get the
most of its optimizer.
Setting the racket @seclink[#:doc '(lib
"scribblings/reference/reference.scrbl") "logging"]{logging} facilities to the
@racket['warning] level when compiling a Typed Racket program causes
the optimizer to log each optimization it performs. Setting the Racket
logging level can be done on the command line with the @racket[-W]
flag:
@commandline{racket -W warning my-typed-program.rkt}
@(define log (open-output-string))
@(define the-eval (make-base-eval))
@(for-each the-eval
'((define sandbox-receiver
(make-log-receiver (current-logger) 'warning))
(thread
(lambda ()
(let loop ()
(printf "~a\n" (vector-ref (sync sandbox-receiver) 1))
(loop))))
(require typed/racket)))
For example, the addition in the following program can be optimized:
@(racketmod+eval #:eval the-eval typed/racket
(: add-two-floats : Float Float -> Float)
(define (add-two-floats x y) (+ x y)))
@; This is very ugly, but necessary to let the log-receiver thread
@; catch up before we ask for the sandbox's output.
@; Suggestions for better solutions welcome.
@(sleep 1)
With optimizer logging turned on, the optimization is reported:
@(commandline (get-output the-eval))
@; TODO doing this in a sandbox breaks source location
In addition, the optimizer also reports cases where an optimization was
close to happening, but was not ultimately safe to perform. Such missed
optimization warnings usually provide explanations as to why an
optimization could not be performed, pointing to changes to your
program that would make it more amenable to optimization.
For example, the multiplication below cannot be safely optimized (see
above discussion about mixing reals and floats), although it may look
like it can.
@(racketmod+eval #:eval the-eval typed/racket
(: mul-int-float : Integer Float -> Real)
(define (mul-int-float x y) (* x y)))
@; Again.
@(sleep 1)
With optimizer logging turned on, the missed optimization is reported:
@(commandline (get-output the-eval))
@; TODO sandboxing also breaks "unexpansion" for printing
@(close-eval the-eval)