Какого повышения производительности мы можем ожидать по мере развития Perl 6?

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

27
задан Pat 5 November 2018 в 17:15
поделиться

4 ответа

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

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

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

Обновление от 23.08.2010

Дополнительная информация от Джонатана Уортингтона о типах изменений, которые должны произойти с объектной моделью Perl 6. (или, по крайней мере, в концепции Ракудо), чтобы сделать вещи быстрыми, сохранив природу Perl 6 «все является вызовом методов».

Обновление от 10.01.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 раз быстрее.

17
ответ дан 28 November 2019 в 05:06
поделиться

Конечно, это не потому, что все является объектом , потому что это верно и для ряда других языков (например, Ruby). Нет никаких причин, почему Perl 6 должен был бы быть на несколько медленнее, чем другие языки, такие как Perl 5 или Ruby, но факт в том, что Rakudo не настолько зрел, как Perl или CRuby. Оптимизация скорости еще не проводилась.

5
ответ дан Leon Timmermans 5 November 2018 в 17:15
поделиться

Ракудо так медлителен по разным причинам.

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

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

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

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

22
ответ дан 28 November 2019 в 05:06
поделиться

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

#!/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 неэффективна, см. комментарии ниже и http://justrakudoit.wordpress.com/2010/06/30/rakudo-and-speed/ .

3
ответ дан 28 November 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: