Is it slower?
What penalty does it impose over two (or more), separate (differently named) subroutines?
Ie. Is the syntactic sugar worth the implementation costs?
A simple test I thought might be useful:
my $t;
sub a {};
sub b {};
multi sub c (1) {};
multi sub c (2) {};
for ^7 {
my $iterations = ^10 ** $_;
say $iterations.max ~ " calls";
$t = now;
for ^$iterations { $_ %% 2 ?? a() !! b() };
say "regular: {now - $t}";
$t = now;
for ^$iterations { c($_ %% 2 ?? 1 !! 2) };
say "multi: {now - $t}";
}
With a recent Rakudo on MoarVM:
1 calls
regular: 0.00630924
multi: 0.0046663
10 calls
regular: 0.00344620
multi: 0.00392575
100 calls
regular: 0.0056468
multi: 0.0079017
1000 calls
regular: 0.0238749
multi: 0.02800533
10000 calls
regular: 0.0541161
multi: 0.287505
100000 calls
regular: 0.43776129
multi: 2.39229575
1000000 calls
regular: 4.45541020
multi: 24.2623499
Unfortunately the numbers are clearly pretty useless.
I hope to l follow up this upcoming week when I've got a better handle on how to usefully answer your question. I'm thinking I'll install perl6-bench which has robust logic for squeezing noise (startup, gc, etc.). out of results. Other than the noise in the numbers, perhaps you could confirm the basic benchmark I created is a reasonable test in principle to answer your question?
Update
I believe the "benchmark" I used above caused confusion in this thread due to its inclusion of implicit `where` constraints (where the argument had the value 1 or 2). These literal fixed value `where` constraints are supposed to one day be resolvable at compile-time but as I write this (April 2015) they are resolved at run-time.
So here's an alternative "benchmark":
my $t;
class A {};
class B {};
sub a (A $a) {};
sub b (B $a) {};
multi sub c (A $a) {};
multi sub c (B $a) {};
for ^7 {
my $iterations = ^10 ** $_;
say $iterations.max ~ " calls";
$t = now;
for ^$iterations { $_ %% 2 ?? a(A) !! b(B) };
say "regular: {now - $t}";
$t = now;
for ^$iterations { c($_ %% 2 ?? A !! B) };
say "multi: {now - $t}";
}
And the timing results:
1 calls
regular: 0.00321471
multi: 0.00306454
10 calls
regular: 0.0029107
multi: 0.0029139
100 calls
regular: 0.0032379
multi: 0.00331093
1000 calls
regular: 0.0091466
multi: 0.00742758
10000 calls
regular: 0.04885046
multi: 0.053550
100000 calls
regular: 0.5330036
multi: 0.5973669
1000000 calls
regular: 5.6755910
multi: 5.946978
So, as I tried to explain in other comments in this thread, type checking and candidate ordering of multisub calls are generally completed at compile-time, just like regular subs.
|