Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 随着Perl 6实现的成熟,我们可以期望什么样的性能提高?_Performance_Raku_Rakudo - Fatal编程技术网

Performance 随着Perl 6实现的成熟,我们可以期望什么样的性能提高?

Performance 随着Perl 6实现的成熟,我们可以期望什么样的性能提高?,performance,raku,rakudo,Performance,Raku,Rakudo,每次下载Rakudo Perl 6的新副本时,我都会运行以下表达式,以了解其当前性能: say [+] 1 .. 100000; 速度一直在增加,但每次计算都有明显的延迟(几秒钟)。作为比较,Perl 5(或其他解释语言)中的类似内容几乎立即返回: use List::Util 'sum'; print sum(1 .. 100000), "\n"; 或者使用Ruby(也几乎是即时的): 将表达式重写为Perl6循环的速度大约是缩小范围的两倍,但对于简单计算来说,这仍然是一个非常明显的延迟

每次下载Rakudo Perl 6的新副本时,我都会运行以下表达式,以了解其当前性能:

say [+] 1 .. 100000;
速度一直在增加,但每次计算都有明显的延迟(几秒钟)。作为比较,Perl 5(或其他解释语言)中的类似内容几乎立即返回:

use List::Util 'sum';

print sum(1 .. 100000), "\n";
或者使用Ruby(也几乎是即时的):

将表达式重写为Perl6
循环
的速度大约是缩小范围的两倍,但对于简单计算来说,这仍然是一个非常明显的延迟(超过一秒):

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

循环(我的$x=1;$x这当然不是因为一切都是对象,因为在许多其他语言中也是如此(比如Ruby)没有理由说Perl 6必须比其他语言(如Perl 5或Ruby)慢多少,但事实是Rakudo没有Perl或CRuby那么成熟。速度优化还不多。

Rakudo这么慢的原因有很多

第一个也是可能是最重要的原因是Rakudo还没有做任何优化。目前的目标是更多地探索新功能,并变得更健壮。你知道,他们说“首先让它运行,然后让它正确,然后让它快速”

第二个原因是parrot还没有提供任何JIT编译,垃圾收集器也不是最快的。有计划开发一个JIT编译器,人们正在开发它(前一个编译器被删除了,因为它只是i386,而且是一个维护噩梦).也有将Rakudo移植到其他虚拟机的想法,但这肯定要等到7月底之后

最后,在我们有一个完整的、优化良好的Perl 6实现之前,没有人能真正知道它的速度有多快,但我确实希望它会比现在好得多

顺便说一句,您引用的案例可以在O(1)中运行,因为
1..$big\u number
返回一个范围,该范围是可内省的。因此您可以对
[+]使用求和公式Range
case。同样,这是可以做到的,但还没有做到。

我在2008年12月提交了这些。
wp.pugs.pl
是Perl 5示例的直译,
wp.rakudo.pl
要大得多。我有两个程序,因为这两个程序实现了规范构建信息的不同子集同时,on已过时。来源:

#!/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帕格斯
#哈巴狗:
#先决条件:ghc-6.8.x,而不是6.10.x
#svn公司http://svn.pugscode.org/pugs/
#perl Makefile.PL
#制造
#如果生成因haskeline而停止,请执行以下操作:
#$HOME/.cabal/bin/cabal更新;$HOME/.cabal/bin/cabal安装haskeline
#了解更多信息:
我的%字;
对于={
对,分开{
%单词{$}++
}
}
对于(排序{%words{$^b}%words{$^a},%words.keys){
说“$\%words{$\}”
}

!/usr/bin/env perl6
#拉库多:
#svn公司http://svn.perl.org/parrot/trunk 鹦鹉
#perl Configure.pl
#制造perl6
#Frank W.和Moritz Lenz提供的解决方案
# 
#了解更多信息:
我的%字;
$*IN.lines.split(/\s+/).map:{%words{$}++};
对于%words.pairs.sort:{$^b.value$^a.value}->$pair{
比如说$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.plfoo
实际0m2.529s
用户0m2.464s
系统0m0.064s
$time./wp.rakudo.plfoo
真正的0m32.544s
用户0m1.920s
系统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
$time./wp.pugs.plfoo
实际0m5.105s
用户0m4.898s
系统0m0.096s
$time./wp.rakudo.plfoo
除零
当前指令:''pc-1((未知文件):-1)
分段故障
实0m3.236s
用户0.447s
sys 0m0.080s

延迟添加:崩溃已在处处理。Rakudo程序效率低下,请参阅和。

关于缺乏优化,您必须了解的另一件事是,它是复杂的。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
并优化掉方法调用,所以在Rakudo找到
之前有一个完整的动态调度>多子中缀:(Num$a,Num$b)
并意识到它真正做的只是一个“添加”操作码。这是比Perl 5慢100-1000倍的合理借口:)

2010年8月23日更新 关于Perl 6对象模型(或者至少是Rakudo对它的概念)需要进行的各种更改,以便在保持Perl 6的“一切都是方法调用”特性的同时加快速度

更新日期:2019年1月10日 因为我可以看到,这仍然受到关注……多年来,Rakudo/MoarVM已经获得了JIT、内联、动态专门化,以及许多人优化系统每个部分的大量工作。结果是大多数方法调用都可以“编译出来”Perl 6在许多基准测试中的得分比2010年快了数百倍或数千倍,在某些情况下甚至比Perl 5快

对于问题开始时的和100000问题,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
但是如果我们通过运行代码10000次来分摊启动成本,w
for @.list {
    @args.push($_);
    if (@args == $arity) {
        my $res = $expression.(@args[0], @args[1]);
        @args = ($res);
    }
}
$ 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
$ 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 -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