每次我下载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
构造比 [+]
减少算子更快?我认为循环会导致更多的总操作而不是减少 .
编辑:
如果可以的话,我会接受 mortiz
和_707268的答案 . 一切都是作为一个方法调用处理更直接的答案为什么 [+]
慢,所以一个人得到它 .
5 回答
关于缺乏优化,你必须要了解的另一件事是它复杂化了 . Rakudo的很大一部分是用Perl 6编写的 . 例如,
[+]
运算符是通过方法Any.reduce
(用$expression
设置为&infix:<+>
调用)实现的,它具有内部循环换句话说,reduce的纯perl实现,它本身由Rakudo运行 . 因此,您看到的代码不仅没有得到优化,而且您没有看到使代码运行的代码也没有得到优化 . 甚至
+
运算符的实例实际上也是方法调用,因为尽管Num
上的+
运算符是由Parrot实现的,但's nothing yet in Rakudo to recognize that you'已经有两个Num
并且优化了方法调用,所以在Rakudo找到multi sub infix:<+>(Num $a, Num $b)
之前有一个完整的动态调度并且意识到所有's really doing is an '添加' opcode. It'是一个合理的借口,比Perl 5慢100-1000倍:)更新8/23/2010
More information from Jonathan Worthington关于Perl 6对象模型需要发生的各种变化(或者至少是Rakudo 's conception of it) to make things fast while retaining Perl 6' s "everything is method calls"性质 .
Rakudo如此缓慢有各种各样的原因 .
第一个也许是最重要的原因是Rakudo还没有进行任何优化 . 目前的目标是更多探索新功能,并变得更加强大 . 你知道,他们说“首先使它运行,然后使其正确,然后使其快速” .
第二个原因是parrot还没有提供任何JIT编译,垃圾收集器也不是最快的 . 有一个JIT编译器的计划,人们正在研究它(前一个被扯掉,因为它只是i386和维护噩梦) . 还有将Rakudo移植到其他虚拟机的想法,但这肯定会等到7月底之后 .
最后,没有人能够真正地告诉我们有一个完整的,经过优化的Perl 6实现的速度有多快,但我确实认为它比现在要好得多 .
顺便说一下你引用
[+] 1..$big_number
的情况可以在O(1)中运行,因为1..$big_number
返回一个范围,这是内省的 . 因此,您可以使用[+] Range
案例的总和公式 . 它再次完成了's something that could be done, but that hasn' .它当然不是因为一切都是一个对象,因为没有理由为什么Perl 6必须比Perl 5或Ruby等其他语言的速度慢,但事实是Rakudo并不像perl或CRuby那样成熟 . 目前还没有太多的速度优化 .
我在2008年12月将这些内容提交给了Fefe's language competition .
wp.pugs.pl
是Perl 5示例的字面翻译,wp.rakudo.pl
更加简单 . 我有两个程序,因为这两个程序实现了规范的不同子集 . 同时,构建信息已过时 . 消息来源:这些是2008年的结果:
今天:
延迟补充:崩溃已在Why do I get 'divide by zero` errors when I try to run my script with Rakudo?处理 . Rakudo程序效率低下,见comments below和http://justrakudoit.wordpress.com/2010/06/30/rakudo-and-speed/ .
考虑到现在你的测试用例是optimized to an O(1) algorithm几乎立即返回,并且看起来几乎就像每周有几个优化;
我期待全面的性能提升 .
即使这不是针对范围的特殊情况,它仍然比它快得多 .
它现在可以在不到五分之一秒的时间内完成测试计算 .