performance perl perl6 rakudo

performance - ¿Qué rendimiento aumenta si esperamos que las implementaciones de Perl 6 maduren?



perl6 rakudo (5)

Cada vez que descargué una nueva copia de Rakudo Perl 6, he ejecutado la siguiente expresión solo para tener una idea de su rendimiento actual:

say [+] 1 .. 100000;

Y las velocidades han ido aumentando, pero cada vez, hay un retraso notable (varios segundos) para el cálculo. Como comparación, algo así en Perl 5 (u otros lenguajes interpretados) retorna casi al instante:

use List::Util ''sum''; print sum(1 .. 100000), "/n";

o en Ruby (también casi instantáneo):

(1 .. 100000).inject(0) {|sum,x| sum+x}

Volver a escribir la expresión como un loop Perl6 termina siendo el doble de rápido que reducir el rango, pero sigue siendo un retraso muy notable (más de un segundo) para el cálculo simple:

my $sum; loop (my $x = 1; $x <= 100000; $x++) {$sum += $x}

Entonces mi pregunta es, ¿qué aspectos de la implementación de Perl6 están causando estos problemas de rendimiento? ¿Y debería mejorar esto con el tiempo, o es este sobrecarga un desafortunado efecto secundario del modelo "todo es un objeto" que Perl6 está usando?

Y, por último, ¿qué pasa con la construcción de loop es más rápida que el operador de reducción [+] ? Pensaría que el ciclo resultaría en más operaciones totales que la reducción.

EDITAR:

hobbs las respuestas de hobbs y hobbs si pudiera. Que todo es un ser manejado como un método de llamada más directa responde por qué [+] está siendo lento, por lo que uno lo consigue.


Ciertamente no es porque todo sea un objeto , porque eso también es cierto en varios otros idiomas (como Ruby). No hay ninguna razón por la cual Perl 6 tenga que ser de una magnitud más lenta que otros lenguajes como Perl 5 o Ruby, pero el hecho es que Rakudo no es tan maduro como perl o CRuby. No ha habido mucha optimización de velocidad todavía.


Hay muchas razones por las que Rakudo es tan lento.

La primera razón y quizás la más importante es que Rakudo aún no optimiza. Los objetivos actuales son más explorar nuevas características y ser más robusto. Ya sabes, dicen "primero hazlo correr, luego hazlo bien, luego hazlo rápido".

La segunda razón es que Parrot no ofrece ninguna compilación de JIT aún, y el recolector de basura no es el más rápido. Hay planes para un compilador JIT, y la gente está trabajando en ello (el anterior fue arrancado porque era solo i386 y una pesadilla de mantenimiento). También se piensa en trasladar Rakudo a otras máquinas virtuales, pero seguramente esperará hasta finales de julio.

Al final, nadie puede decir qué tan rápido será una implementación de Perl 6 completa y bien optimizada hasta que tengamos una, pero espero que sea mucho mejor que ahora.

Por cierto, el caso que citó [+] 1..$big_number podría ejecutarse en O (1), porque 1..$big_number devuelve un Rango, que es introspectible. Entonces puede usar una fórmula de suma para el caso de [+] Range . De nuevo, es algo que se podría hacer, pero eso aún no se ha hecho.


Otra cosa que tienes que entender sobre la falta de optimización es que está compuesta . Una gran parte de Rakudo está escrita en Perl 6 . Entonces, por ejemplo, el operador [+] es implementado por el método Any.reduce (llamado con $expression set to &infix:<+> ), que tiene como su bucle interno

for @.list { @args.push($_); if (@args == $arity) { my $res = $expression.(@args[0], @args[1]); @args = ($res); } }

en otras palabras, una implementación pura-perl de reducir, que en sí mismo está siendo ejecutado por Rakudo. Así que no solo el código que puede ver no se optimiza, el código que no ve que hace que su código se ejecute tampoco se optimiza. Incluso las instancias del operador + son en realidad llamadas de método, ya que aunque el operador + en Num está implementado por Parrot, Rakudo aún no tiene nada que reconozca que tiene dos Num y optimiza la llamada al método, por lo que hay una dinámica completa despacho antes de que Rakudo encuentre multi sub infix:<+>(Num $a, Num $b) y se da cuenta de que todo lo que realmente está haciendo es un opcode ''add''. Es una excusa razonable para ser 100-1000 veces más lento que Perl 5 :)

Actualización 23/08/2010

6guts.wordpress.com/2010/08/22/… sobre los tipos de cambios que deben suceder con el modelo de objetos Perl 6 (o al menos la concepción de Rakudo) para acelerar las cosas sin perder la naturaleza de Perl 6 de "todo es método llama".


Teniendo en cuenta que ahora su caso de prueba está optimizado para un algoritmo O (1) que retorna casi al instante, y que parece casi como si hubiera varias optimizaciones por semana;
Espero una gran mejora en el rendimiento.

$ perl6 -e ''say [+] 1..10**1000; say now - INIT now'' 5000000000000000000000000000000000000000000000 ... 0.007447

Incluso si eso no fuera especial para los rangos, todavía es bastante más rápido de lo que era.
Ahora hace su cálculo de prueba en menos de un quinto de segundo.

$ perl6 -e ''say [+] (1..100000).list; say now - INIT now'' 5000050000 0.13052975


wp.pugs.pl estos a la competencia de idiomas de Fefe en diciembre de 2008. wp.pugs.pl es una traducción literal del ejemplo de Perl 5, wp.rakudo.pl es mucho más setentero. Tengo dos programas porque los dos implementan un subconjunto diferente de la especificación. La información de compilación está desactualizada mientras tanto. Las fuentes:

#!/usr/bin/env pugs # Pugs: <http://pugs.blogs.com/> <http://pugscode.org/> # prerequisite: ghc-6.8.x, not 6.10.x # svn co http://svn.pugscode.org/pugs/ # perl Makefile.PL # make # if build stops because of haskeline, do: # $HOME/.cabal/bin/cabal update ; $HOME/.cabal/bin/cabal install haskeline # learn more: <http://jnthn.net/papers/2008-tcpw-perl64danoob-slides.pdf> my %words; for =<> { for .split { %words{$_}++ } } for (sort { %words{$^b} <=> %words{$^a} }, %words.keys) { say "$_ %words{$_}" }

#!/usr/bin/env perl6 # Rakudo: <http://rakudo.org/> <http://www.parrot.org/download> # svn co http://svn.perl.org/parrot/trunk parrot # perl Configure.pl # make perl6 # Solution contributed by Frank W. & Moritz Lenz # <http://use.perl.org/~fw/journal/38055> # learn more: <http://jnthn.net/papers/2008-tcpw-perl64danoob-slides.pdf> my %words; $*IN.lines.split(//s+/).map: { %words{$_}++ }; for %words.pairs.sort: { $^b.value <=> $^a.value } -> $pair { say $pair }

Estos fueron los resultados en 2008:

$ time ./wp.pugs.pl < /usr/src/linux/COPYING > foo real 0m2.529s user 0m2.464s sys 0m0.064s $ time ./wp.rakudo.pl < /usr/src/linux/COPYING > foo real 0m32.544s user 0m1.920s sys 0m0.248s

Hoy:

$ time ./wp.pugs.pl < /usr/src/linux/COPYING > foo real 0m5.105s user 0m4.898s sys 0m0.096s $ time ./wp.rakudo.pl < /usr/src/linux/COPYING > foo Divide by zero current instr.: '''' pc -1 ((unknown file):-1) Segmentation fault real 0m3.236s user 0m0.447s sys 0m0.080s

Adiciones tardías: el bloqueo se ha solucionado en ¿Por qué obtengo errores de "divide por cero" cuando intento ejecutar mi script con Rakudo? . El programa Rakudo es ineficiente, vea los comentarios a continuación y http://justrakudoit.wordpress.com/2010/06/30/rakudo-and-speed/ .