是否有关于Perl 6中类型/约束的性能惩罚的研究?

时间:2017-02-08 15:21:17

标签: performance perl6

与Perl 5相比,Perl 6引入了可选类型以及约束,例如:

# Perl 5
sub mySub {
   my $probability = $_[0];
   # Do stuff with $probability
}

# Perl 6 - using optional typing and constraints
sub mySub(Real $probability where 0 < * < 1) {
   # Do stuff with $probability
}

在使用这些功能时,有没有研究调查是否存在性能损失,以及它们在不同的Perl 6 VM上有多大?

我正在寻找设计合理的东西,并且跨越VM。

2 个答案:

答案 0 :(得分:4)

Perl 6的最完整和精心设计的性能测量工作是https://github.com/japhb/perl6-bench,但它没有关注可选输入的相对性能。但它确实支持多个VM后端,因此它可能是一个很好的起点。

答案 1 :(得分:3)

这个答案旨在补充@ donaldh的答案,虽然我也不知道任何针对Perl 6类型/类型约束的研究。

静态类型检查很快

在下面,编译器在编译时执行Complex ~~ Real类型检查

sub mySub(Real $probability where 0 < * < 1) {
    # Do stuff with $probability
}

my Complex \number = 1-2e3i;

mySub number;

编译上面的代码,Rakudo编译器意识到numberComplex - 所以你得到编译时类型检查失败:

===SORRY!=== Error while compiling

Calling mySub(Complex) will never work with declared signature (Real $probability)

随着时间的推移,像Rakudo这样的Perl 6编译器可以改进编译时代码分析,从而导致在编译时发生更多的类型检查,如上所述。

请注意,where条款甚至没有尝试过。仅仅指定 where子句就会受到零惩罚。由where子句引起的任何开销仅在变量/值超过基本类型检查时才适用。

大多数动态类型检查也很快

在下面,编译器在运行时进行Complex ~~ Real类型检查:

multi sub mySub(Real $probability where 0 < * < 1) {
    # Do stuff with $probability
}

multi sub mySub(Complex $probability) {
    # Do stuff with $probability
}

my \number = 1-2e3i;

mySub number;

编译上面的代码,Rakudo编译器 not 目前在编译时意识到numberComplex。在运行时,它会考虑并拒绝第一个multi sub声明。和以前一样,它甚至不会尝试where子句。相反,它会成功调用第二个multi sub

到目前为止的示例应该清楚地表明,对于大多数类型检查,运行时性能损失为零或几乎为零。

原生类型

理论上,本机类型可用于提高性能:

sub foo-Int (Int $a) { my Int $b; $b++ for ^$a }
sub foo-int (int $a) { my int $b; $b++ for ^$a }

my $time;
$time = now; foo-Int my Int $ = 1e6.Int; say now - $time; # 1.0597491
$time = now; foo-int my int $ = 1e6.Int; say now - $time; # 0.7627174

实际上,指定本机类型有时会降低代码速度。

随着Rakudo优化的改进,相对于int的{​​{1}}优化应该变得更加一致且更加重要。类似的故事适用于其他本地标量类型和本机数组。

强制类型

Perl 6支持&#34;强制类型&#34;。

例如,Int接受任何Str(Int)或其子类型并强制转换为Int

如果强制类型的内部类型匹配,则编译器也会产生运行强制代码的运行时开销。

Str条款

完成上述传统的静态和动态类型检查后,将调用任何适用的where子句,直到其中一个成功或全部失败。

编译器可以自由地分析where子句并意识到它们等同于一个足够简单的静态类型表达式(例如where)并使用此信息来避免运行任意运行所产生的运行时开销码。 (参见@Larry's speculation about related matters。)

目前的Rakudo不分析where Int | Str条款。实际上,它会更频繁地调用where子句。

编译器

性能是特定编译器/后端的功能。

2017年开始的主要Perl 6编译器是Rakudo / MoarVM。过去还有其他编译器编译了Perl 6和there surely will be again的重要子集;这些可能会提供额外的数据。

“可选键入”与“逐步键入”

  

Perl 6引入了可选输入

如果您决定在网上搜索相关数据......

Perl 6支持基于类的继承和多分派等功能。根据维基百科的definition,这两者在技术上都取消了Perl 6的“可选打字”系统的资格。

维基百科将Perl 6放在广泛的类别“Gradual Typing”中,Larry Wall和doc.perl6.org也是如此。