domingo, 24 de fevereiro de 2008

Otimização de código em Lisp

O Lisp pode funcionar com dynamic typing ou static typing, sendo que no segundo caso não é feita promoção automática de tipos como no C. Portanto se vc declara que uma função recebe double-float, ela só pode receber double floats.

Existem 3 tipos de declações de tipos no lisp:

1) (defun f (x)
(declare (type fixnum x))
(1+ x))

O declare serve como dica para o compilador otimizar o código. Dependendo de como estiverem as declarações de otimização podem este declare pode gerar códigos diferentes, dependendo das diretivas de otimização:

(defun speedy-f (x)
(declare (type fixnum x)
(otimize (speed 3)))
(1+ x))

Vai gerar um código otimizado para inteiros e que sinaliza um erro caso seja passado outro tipo de dado. Porém:

(defun speedy-unsafe-f (x)
(declare (type fixnum x)
(otimize (speed 3) (safety 0)))
(1+ x))

Vai gerar um código que aceita qualquer coisa e retorna um resultado errado, no meu computador:

(speedy-unsafe-f 1d0)

=> 8599862262

2) O coerce é uma função que gera explicitamente o código de conversão de tipo. Por exemplo

(loop for x from 1 to 10 sum (/ x))
=> 7381/2520



(loop for x from 1 to 10 sum (/ (coerce x 'float)))
=> 2.9289684

3) Por fim existe a declaração da assinatura da função:

(declaim (ftype (function (fixnum) fixnum) f))
(defun f (x)
(declare (type fixnum x))
(1+ x))

Que pode ajudar na otimização na chamada de f.

Existe muito pouca documentação em como criar códigos otimizados no lisp. Experimentação, ler códigos otimizados de outros e as mensagens de compilação do SBCL (principalmente com o highlight do SLIME) são as maneiras de aprender como faze-lo.

Nenhum comentário: