Какую производительность увеличивается, мы можем ожидать в качестве реализации Perl 6 зрелых?

StackOverflow https://stackoverflow.com/questions/3135673

Вопрос

Каждый раз, когда я скачал новую копию Rakudo Perl 6, я выполнил следующее выражение, чтобы получить представление о своей текущей производительности:

say [+] 1 .. 100000;

И скорость увеличиваются, но каждый раз, есть заметная задержка (несколько секунд) для расчета. Как сравнение, что-то подобное в Perl 5 (или других интерпретированных языках) возвращается почти мгновенно:

use List::Util 'sum';

print sum(1 .. 100000), "\n";

или в Ruby (также почти мгновенно):

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

Переписать выражение в качестве Perl6 loop заканчивается примерно в два раза быстрее, что снижает диапазон, но оно все еще очень заметное задержка (более секунды) для простого расчета:

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

Таким образом, мой вопрос, какие аспекты реализации Perl6 вызывают эти проблемы производительности? И если это улучшится со временем, или это накладные расходы на несчастный побочный эффект «все является объектом», которую использует Perl6?

И, наконец, как насчет loop конструкция быстрее, чем [+] Оператор сокращения? Я бы подумал, что цикл приведет к более общему общему OPS, чем уменьшение.

РЕДАКТИРОВАТЬ:

Я бы примет оба mortiz'песок hobbsответы, если бы я мог. Что все обрабатывается как метод позвоните больше напрямую ответов, почему [+] не медленно, так что их получает.

Это было полезно?

Решение

Еще одна вещь, которую вы должны понимать о отсутствии оптимизации, это то, что это усугубляется. Отказ Большая часть Ракудо написана в Perl 6.. Отказ Так, например, [+] Оператор реализован методом Any.reduce (называется с $expression установлен в &infix:<+>), который имеет свой внутренний цикл

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

Другими словами, реализация чистого Perl снижения, которая сама проходит Ракудо. Так что не только код, который вы можете видеть не оптимизирован, код, который вы нет См. Это делает ваш код кода также не оптимизирован. Даже случаи + оператор на самом деле метод вызовы, поскольку хотя + Оператор включен Num реализуется попугаем, в Ракудо ничего нет ничего, чтобы узнать, что у вас есть два NumS и оптимизировать вызов метода, поэтому есть полная динамическая отправка до того, как Rakudo находит multi sub infix:<+>(Num $a, Num $b) И понимает, что все это действительно делает, - это ООО «Добавить» код. Это разумное оправдание для того, чтобы быть 100-1000x медленнее, чем Perl 5 :)

Обновление 8/23/2010.

Больше информации от Джонатана Уортингтона На видах изменений, которые необходимо случиться с объектной моделью Perl 6 (или, по крайней мере, концепцией Rakudo), чтобы сделать все возможное, сохраняя при этом природу Perl 6's «Все - это метод вызывает« природа ».

Обновление 1/10/2019.

Поскольку я вижу, что это все еще привлечение внимания ... На протяжении многих лет Rakudo / MoArvm получили JIT, встроившиеся, динамичные специализации и тонн Работа многими людьми, оптимизирующими каждую часть системы. Результатом заключается в том, что большинство из этих вызовов метода могут быть «компилированы» и имеют почти нулевое затрат за выполнением. Perl 6 забивает сотни или тысячи раз быстрее на многих тестах, чем в 2010 году, и в некоторых случаях это быстрее, чем Perl 5.

В случае проблемы с суммой до 100 000 о том, с чем началось вопрос, Rakudo 2018.06 все еще немного медленнее, чем Perl 5.26.2:

$ time perl -e 'use List::Util 'sum'; print sum(1 .. 100000), "\n";' >/dev/null

real    0m0.023s
user    0m0.015s
sys     0m0.008s

$ time perl6 -e 'say [+] 1 .. 100000;' >/dev/null

real    0m0.089s
user    0m0.107s
sys     0m0.022s

Но если мы амортизируем стоимость запуска, запустив код 10 000 раз, мы видим другую историю:

$ time perl -e 'use List::Util 'sum'; for (1 .. 10000) { print sum(1 .. 100000), "\n"; }' > /dev/null

real    0m16.320s
user    0m16.317s
sys     0m0.004s

$ time perl6 -e 'for 1 .. 10000 { say [+] 1 .. 100000; }' >/dev/null

real    0m0.214s
user    0m0.245s
sys     0m0.021s

PERL6 использует несколько сотен более миллисекунд, чем Perl5 при запуске и компиляции, но затем он выясняет, как сделать фактическое суммирование около 70 раз быстрее.

Другие советы

Есть действительно разные причины, почему Ракудо так медленно.

Первая и, возможно, самая важная причина в том, что Rakudo еще не выполняет оптимизацию. Текущие цели более изучают новые функции и стать более надежными. Вы знаете, они говорят: «Сначала заставляй его бежать, а затем сделать это правильно, а затем сделать его быстро».

Вторая причина в том, что попугай не предлагает никакой компиляции JIT, а сборщик мусора не самый быстрый. Есть планы на JIT Compiler, и люди работают над ним (предыдущий был разорван только потому, что это был только I386, а на кошмаре обслуживания). Есть также мысли о портировании Ракудо в другие виртуальные машины, но это наверняка ждет до конца июля.

В конце концов, никто не может по-настоящему рассказать, как быстро будет полная, хорошо оптимизированная реализация Perl 6, пока у нас будет один, но я ожидаю, что это будет намного лучше, чем сейчас.

Кстати, если вы указали [+] 1..$big_number может быть сделано для запуска в O (1), потому что 1..$big_number Возвращает диапазон, который является самосвалом. Так что вы можете использовать формулу суммы для [+] Range кейс. Опять же, это то, что можно было сделать, но это еще не было сделано.

Это, конечно, не потому, что Все это объект, Потому что это правда в ряде других языков тоже (например, Ruby). Нет никаких причин, по которым Perl 6 должен быть величины медленнее, чем другие языки, такие как Perl 5 или Ruby, но тот факт, что Ракудо не такой зрелый, как Perl или Crobyy. Там еще не было много оптимизации скорости.

Учитывая, что теперь ваш тестовый случай Оптимизирован для AN O (1) алгоритм Это возвращается почти мгновенно, и что кажется, что есть несколько оптимизаций в неделю;
Я ожидаю, что довольно совершенное улучшение производительности.

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

Даже если это не было спецнаженным для диапазонов, это все еще совсем немного быстрее, чем было.
Теперь он делает ваш расчет теста менее пятой секунды.

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

Я отправил это Языковая конкуренция FEFE в декабре 2008 года. wp.pugs.pl это буквальный перевод примера Perl 5, wp.rakudo.pl гораздо более Sixier. У меня есть две программы, потому что два реализуют другое подмножество спецификации. Информация по сборке устарела тем временем. Источники:

#!/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
}

Это были результаты в 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

Сегодня:

$ 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

Поздние дополнения: авария была решена в Почему я получаю «разделить на нулевые ошибки, когда я пытаюсь запустить свой сценарий с Rakudo?. Отказ Программа Rakudo неэффективна, см. Комментарии ниже а также http://justrakudoit.wordpress.com/2010/06/30/rakudo-and-speed/.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top