2009/7/6 Jeronimo Pellegrini <[email protected]>

>
> On Mon, Jul 06, 2009 at 12:26:22AM -0300, Gustavo wrote:
> > Olá pessoal da lista,
>
> Olá -- boa madrugada!


Olá! Bom dia!

>
>
> > Acabei de fazer uma descoberta que vai contra a minha intuição.
> >
> > Estava testando eficiência com arrays de inteiros (de (unsigned-byte 64)
> > para ser mais exato) e descobri que arrays não ajustáveis são 10 vezes
> mais
> > eficientes que as ajustáveis! Eu imaginava que não deveria haver
> diferença,
> > porque, por exemplo, em C, se você aloca um array dinamicamente (com
> > malloc), esse array é automaticamente ajustável (com realloc).
>
> Mas o adjust-array funciona com arrays não-ajustáveis. Se não me engano,
> você não tem mais garantia que o array será o mesmo objeto:
> (EQ array-antigo array-novo)
> pode ser NIL.


Verdade! Você tem razão, adjust-array funciona com qualquer array, embora:

cl-user> (make-array 20)
#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
cl-user> (eq * (adjust-array * 30))
nil

Aliás, acho que essa foi uma excelente escolha pelo pessoal que fez a spec!


> Este é o código que uso para ajustar arrays no
> Spartns [0]:
>
> (defun robust-adjust-array (array size &key (element-type nil))
>  "Adjusts the size of an array, setting it to the new one. Also works
> around an issue with Allegro Common Lisp: in ACL, when you call
> adjust-array on a non-adjustable array, the resulting array is not
> necessarily of the same type. It is not a SIMPLE-ARRAY
> anymore.  Dependig on how you try to fix it, you may end up with an
> array whose element-type is T. So, this is a method for resizing an
> array and keeping the same array type.
>
> Yes, we want SIMPLE-ARRAYs because access is faster. But we also want to
> adjust them, even if adjusting is slow."
>  (let ((type (if (null element-type)
>                  `(array-element-type ,array)
>                  element-type)))
>    (setf array
>          #-allegro (adjust-array array size :element-type type)
>          #+allegro (coerce (adjust-array array size :element-type type
>                                                     :adjustable nil)
>                            `(simple-array ,type *)))
>    array))
>
> Note que o código não necessariamente altera seu array; ele retorna outro!
>
>  > (setf a (make-array 5 :element-type 'fixnum))
>  > a
>  #(0 0 0 0 0)
>  > (type-of a)
>  (SIMPLE-ARRAY FIXNUM (5))
>  > (setf b (robust-adjust-array a 10))
>  > (type-of a)
>  (SIMPLE-ARRAY FIXNUM (5))
>  > a
>  #(0 0 0 0 0)
>  > b
>  #(0 0 0 0 0 0 0 0 0 0)
>  > (type-of b)
>  (SIMPLE-ARRAY FIXNUM (10))
>
> > Também descobri que, felizmente, você pode declarar uma array como sendo
> do
> > tipo simple-array para poder aproveitar essa eficiência (simple-arrays
> são
> > arrays não-ajustáveis, sem fill-pointer e sem "displacement" (i.e. arrays
> > que são criadas sem passar o argumento :displace-to)).
> >
> > A única explicação que eu consigo pensar é que, se uma array ajustável é
> > criada, o sbcl identifica seu tipo como sendo uma array "normal" (ao
> invés
> > de identificá-la como uma simple-array), o que faz com que ele não
> consiga
> > otimizar as chamadas para aref porque o tipo array "normal" não
> diferencia
> > arrays com "displacement" ou sem "displacement".
>
> Não só o SBCL; isso está previsto no padrão ANSI. Um simple-array é
> aquele que não é ajustável, sem overlap com outro, e sem fill-pointer.
> E a idéia é justamente permitir otimizações.


Na verdade, não é exatamente assim. A specificação diz que uma array que não
é ajustável, não tem fill-pointer e sem "overlap" é uma simples array, mas
que é "implementation-dependent" se a recíproca é verdadeira (em outras
palavras, uma implementação pode considerar todas as arrays como sendo
simple-arrays). De acordo com o spec (na especificação sobre o tipo
SIMPLE-ARRAY):

"It is 
*implementation-dependent*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_i.htm#implementation-dependent>whether
*displaced 
arrays*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_d.htm#displaced_array>,
*vectors*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_v.htm#vector>with
*fill 
pointers*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#fill_pointer>,
or arrays that are *actually
adjustable*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_a.htm#actually_adjustable>are
*simple 
arrays*<http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_s.htm#simple_array>.
"

Aliás, é até possível que, numa implementação específica, todas as arrays
sejam ajustáveis por padrão.

Porém, na minha intuição, apenas o "overlap" é que pode dificultar a
otimização (especialmente overlap de arrays multi-dimensionais), então eu
imaginava que o sbcl, sendo esperto, só não iria considerar como sendo
simple-arrays as arrays com overlap.

Bom, enfim, não fui eu quem fiz o sbcl, então não vou reclamar ;)

>
>
> > Poder
> > usar arrays ajustáveis sem problemas com a eficiência iria quebrar o
> galho
> > no que eu pretendo fazer (embora não seja totalmente necessário, mas vou
> ter
> > que sair copiando uma parte da array).
>
> Do modo como eu propus pode ser que *o ajuste* fique lento, mas o acesso é
> tão rápido quanto em C.


Isso é bom :)
E o bom também é que, se alguma implementação considerar todas as arrays
como sendo ajustáveis, usar o adjust-array fará o meu projeto acabar
automaticamente usando essa vantagem (mas será que alguma implementação faz
isso? Nem o clisp nem o ecl fazem isso).
De qualquer forma, é o que eu preciso. Os ajustes das arrays não devem ser
muito frequentes mesmo (de acordo com a lei da probabilidade), então esse
problema de tempo do ajuste não vai importar muito.

Obrigado pela resposta, ajudou muito :)

>
>
> J.
>
> [0] http://aleph0.info/spartns
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lisp-br" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/lisp-br?hl=en
-~----------~----~----~----~------~----~------~--~---

Responder a