From 83c6f990419b711e9d894e49536256834c97d029 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 2 Aug 2010 10:35:17 -0400 Subject: [PATCH] Documented the optimizer. original commit: cb516081c742cfeb04d754d4925389de33319cd7 --- .../scribblings/optimization.scrbl | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/collects/typed-scheme/scribblings/optimization.scrbl b/collects/typed-scheme/scribblings/optimization.scrbl index e7d70054..dc576155 100644 --- a/collects/typed-scheme/scribblings/optimization.scrbl +++ b/collects/typed-scheme/scribblings/optimization.scrbl @@ -19,3 +19,92 @@ want to activate it, you must add the @racket[#:optimize] keyword when specifying the language of your program: @racketmod[typed/racket #:optimize] + +@section{Getting the most out of the optimizer} +Typed Racket's optimizer can improve the performance of various common +Racket idioms. However, it does a better job on some idioms than on +others. By writing your programs using the right idioms, you can help +the optimizer help you. + +@subsection{Numeric types} +Being type-driven, the optimizer makes most of its decisions based on +the types you assigned to your data. As such, you can improve the +optimizer's usefulness by writing informative types. + +For example, the following programs both typecheck: +@racketblock[(define: (f (x : Real)) : Real (+ x 2.5)) + (f 3.5)] +@racketblock[(define: (f (x : Float)) : Float (+ x 2.5)) + (f 3.5)] + +However, the second one uses more informative types: the +@racket[Float] type includes only inexact real numbers whereas the +@racket[Real] type includes both exact and inexact real numbers. Typed +Racket's optimizer can optimize the latter program to use +inexact-specific operations whereas it cannot do anything with the +former program. + +Thus, to get the most of Typed Racket's optimizer, you should use the +@racket[Float] type when possible. + +On a similar note, the @racket[Inexact-Complex] type is preferable to +the @racket[Complex] type for the same reason. Typed Racket can keep +inexact complex numbers unboxed; as such, programs using complex +numbers can have better performance than equivalent programs that +represent complex numbers as two real numbers. To get the most of +Typed Racket's optimizer, you should also favor rectangular +coordinates over polar coordinates. + +@subsection{Lists} +Typed Racket handles potentially empty lists and lists that are known +to be non-empty differently: when taking the @racket[car] or the +@racket[cdr] of a list Typed Racket knows is non-empty, it can skip +the check for the empty list that is usually done when calling +@racket[car] and @racket[cdr]. + +@racketblock[ +(define: (sum (l : (Listof Integer))) : Integer + (if (null? l) + 0 + (+ (car l) (sum (cdr l))))) +] + +In this example, Typed Racket knows that if we reach the else branch, +@racket[l] is not empty. The checks associated with @racket[car] and +@racket[cdr] would be redundant and are eliminated. + +In addition to explicitly checking for the empty list using +@racket[null?], you can inform Typed Racket that a list is non-empty +by using the known-length list type constructor; if your data is +stored in lists of fixed length, you can use the @racket[List] type +constructors. + +For instance, the type of a list of two @racket[Integer]s can be +written either as: +@racketblock[(define-type List-2-Ints (Listof Integer))] +or as the more precise: +@racketblock[(define-type List-2-Ints (List Integer Integer))] + +Using the second definition, all @racket[car] and @racket[cdr]-related +checks can be eliminated in this function: +@racketblock[ +(define: (sum2 (l : List-2-Ints) : Integer) + (+ (car l) (car (cdr l)))) +] + +@subsection{Vectors} + +In addition to known-length lists, Typed Racket supports known-length +vectors through the @racket[Vector] type constructor. Known-length +vector access using constant indices can be optimized in a similar +fashion as @racket[car] and @racket[cdr]. + +@#reader scribble/comment-reader (racketblock +;; #(name r g b) +(define-type Color (Vector String Integer Integer Integer)) +(define: x : Color (vector "red" 255 0 0)) +(vector-ref x 0) ; good +(define color-name 0) +(vector-ref x color-name) ; good +(vector-ref x (* 0 10)) ; bad +)