compiling “premature optimization is the root of all evil.” -donald knuth

10
Compiling “premature optimization is the root of all evil.” -Donald Knuth

Upload: arthur-mitchell

Post on 18-Jan-2016

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Compiling

“premature optimization is the root of all evil.”

-Donald Knuth

Page 2: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Optimization

In LISP, you can write slow code fast or fast code slow

Experience will help you overcome common pitfalls (over use of append in recursive algorithms for example)

In general, worry about the top level algorithms first. You can always speed it up later

Page 3: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Compiling

LISP can be compiled into machine code just like other languages– Typically results in a drastic speed up for LISP

programs

Compilation can reduce both running time and memory consumption

Page 4: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Time a Function

You can see how long it takes to evaluate a function by wrapping the function call in a call to time

(defun waste-time (n) (dotimes (i n) (* i i)))

>(time (waste-time 50000))real time : 0.020 secsrun-gbc time : 0.020 secschild run time : 0.000 secsgbc time : 0.000 secsNIL

Page 5: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Compile

>(time (waste-time 50000000))real time : 21.690 secsrun-gbc time : 20.770 secschild run time : 0.000 secsgbc time : 0.870 secsNIL

>(compile 'waste-time)[…Compiler output…]

>(time (waste-time 50000000))real time : 11.220 secsrun-gbc time : 10.200 secschild run time : 0.000 secsgbc time : 0.950 secsNIL

Page 6: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Disassemble

We can look at the assembly code produced by compile using disassemble System and implementation dependent Here’s an example in CLISP>(defun add1 (n) (1+ n))ADD1>(disassemble 'add1)Disassembly of function ADD11 required argument0 optional argumentsNo rest parameterNo keyword parameters3 byte-code instructions:0 (LOAD&PUSH 1)1 (CALLS2 151) ; 1+3 (SKIP&RET 2)NIL GCL output can be a mess since it actually transforms LISP into C code

Page 7: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Compile-File

You can also compile all functions in a given file

(compile-file "file.lisp") To run functions from the compiled file, load it

like any other file

(load "file.fas") The specific file extension depends on

implementation

Page 8: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Inlining

You can make a function be an inline function by using declare

(defun f (x) (* x x))(defun g (x) (declare (inline f)) (+ (f x) (f x))) Now, upon compiling g, the actual body of f will be

copied into g in the pertinent locations, though only within g.

To make f be an inline function everywhere, use declaim instead of declare, within the global scope.

Cannot be used with recursive functions

Page 9: Compiling “premature optimization is the root of all evil.” -Donald Knuth

More Type Safety

declare and declaim can specify other compiler directives You can use to streamline compiled functions to only expect certain types using

type

>(defun f (x y) (declare (type integer x y)) (+ x y))F>(f 5.6 3.4)9.0>(compile 'f)…Compiler output…>(f 3 4)7>(f 5.6 3.4)Error

Page 10: Compiling “premature optimization is the root of all evil.” -Donald Knuth

Optimizing

The optimize declaration allows several optimization priorities to be set

Priorities are on a scale from 0 to 3, with 3 the most important– compilation-speed: speed of the compilation process – debug: ease of debugging – safety: run-time error checking – space: both code size and run-time space – speed: speed of the object code

Example specification(defun f (x y) (declare (optimize (safety 2) (speed 3))) (+ x y))