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.
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:Compiling the above code the Rakudo compiler realizes that
number
isComplex
-- so you get a compile time type check failure: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 specifyingwhere
clauses. Any overhead due towhere
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:Compiling the above code the Rakudo compiler does not currently realize that
number
isComplex
at compile time. At run time it considers and rejects the firstmulti sub
declaration. As before it doesn't even try thewhere
clause. Instead it makes a successful call to the secondmulti 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:
In practice, specifying a native type will sometimes slow code down.
As Rakudo's optimization improves, the
int
optimization relative toInt
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 anyInt
or a subtype thereof and coerces to aStr
.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
clausesAfter 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 (egwhere 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 invokeswhere
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”
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.
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.