问题
In contrast with Perl 5, Perl 6 introduced optional typing, as well as constraints, e.g.:
# 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
}
Have there been studies that investigate whether there are performance penalties, and how large are they on different Perl 6 VMs, when using these capabilities?
I'm looking for something well designed, and cross-VM.
回答1:
The most complete and well designed performance measurement work for Perl 6 is https://github.com/japhb/perl6-bench but it does not focus on the relative performance of optional typing. It does however have support for multiple VM backends so it might be a good place to start.
回答2:
This answer aims to complement @donaldh's answer though I also don't know of any research specific to Perl 6 types / type constraints.
Static type checking is fast
In the following the compiler does a Complex ~~ Real
type check at compile time:
sub mySub(Real $probability where 0 < * < 1) {
# Do stuff with $probability
}
my Complex \number = 1-2e3i;
mySub number;
Compiling the above code the Rakudo compiler realizes that number
is Complex
-- so you get a compile time type check failure:
===SORRY!=== Error while compiling
Calling mySub(Complex) will never work with declared signature (Real $probability)
Over time Perl 6 compilers like Rakudo can improve their compile time code analysis leading to more type checking happening at compile time like the above.
Note that the where
clause wasn't even tried. There's zero penalty for merely specifying where
clauses. Any overhead due to where
clauses only applies if a variable/value gets past the basic type checks.
Most dynamic type checking is fast too
In the following the compiler does a Complex ~~ Real
type check at run time:
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;
Compiling the above code the Rakudo compiler does not currently realize that number
is Complex
at compile time. At run time it considers and rejects the first multi sub
declaration. As before it doesn't even try the where
clause. Instead it makes a successful call to the second multi sub
instead.
The examples thus far should make it clear that there's either zero or nearly zero run time performance penalty for most type checking.
Native types
In theory, native types may be used for better performance:
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
In practice, specifying a native type will sometimes slow code down.
As Rakudo's optimization improves, the int
optimization relative to Int
should become more consistent and more significant. A similar story applies for other native scalar types and for native arrays.
Coercion types
Perl 6 supports "coercion types".
For example, Str(Int)
accepts any Int
or a subtype thereof and coerces to a Str
.
If the inner type of a coercion type matches, then the compiler will also incur the run-time overhead of running the coercion code.
where
clauses
After completing conventional static and dynamic type checking as described above, any applicable where
clauses are invoked until one of them succeeds or all of them fail.
A compiler is free to analyze where
clauses and realize they are equivalent to a sufficiently simple static type expression (eg where Int | Str
) and use this info to avoid the run time overhead that comes from running arbitrary code. (cf. @Larry's speculation about related matters.)
The current Rakudo does not analyze where
clauses. In fact, it invokes where
clauses more often than it strictly needs to.
Compilers
Performance is a function of particular compilers/backends.
The primary Perl 6 compiler of note as 2017 began was Rakudo/MoarVM. There have been other compilers in the past that compiled significant subsets of Perl 6 and there surely will be again; these may provide additional data.
“Optional Typing” vs “Gradual Typing”
Perl 6 introduced optional typing
In case you decide to search around the net for related data...
Perl 6 supports features like class-based inheritance and multi dispatch. Both of these technically disqualify Perl 6 from having an “Optional Typing” system according to wikipedia's definition.
Wikipedia instead places Perl 6 in the broad category “Gradual Typing” and so does Larry Wall and doc.perl6.org.
来源:https://stackoverflow.com/questions/42117027/is-there-research-on-performance-penalties-for-types-constraints-in-perl-6