Skip to content

Commit

Permalink
Streamline infix:<eqv>
Browse files Browse the repository at this point in the history
- make sure all non-any candidates have :D
- add special Any:U,Any:U candidate
- add special Any:U,Any:D candidate (always False)
- rewrite candidates using nqp ops (except Signature/Parameter)
- add candidates for Str, IntStr, NumStr, RatStr, ComplexStr
- now dies on Seq:D,Seq:D if both are lazy, return False if only one of them is

Improves: Str: 14x, type: 10x, Range: 3.5x, Int|Seq|Hash: 1.5x, Array: 1.2x
  • Loading branch information
lizmat committed Oct 29, 2016
1 parent 627a77e commit bc7fcc6
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 75 deletions.
2 changes: 1 addition & 1 deletion src/core/Capture.pm
Expand Up @@ -143,7 +143,7 @@ my class Capture { # declared in BOOTSTRAP
}
}

multi sub infix:<eqv>(Capture \a, Capture \b) {
multi sub infix:<eqv>(Capture:D \a, Capture:D \b) {
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT)
Expand Down
44 changes: 22 additions & 22 deletions src/core/Map.pm
Expand Up @@ -289,31 +289,31 @@ my class Map does Iterable does Associative { # declared in BOOTSTRAP
}

multi sub infix:<eqv>(Map:D \a, Map:D \b) {
nqp::if(
nqp::eqaddr(a,b),
True,
nqp::if(
(nqp::eqaddr(a.WHAT,b.WHAT) && (my int $elems = a.elems) == b.elems),
nqp::p6bool(
nqp::unless(
nqp::eqaddr(a,b),
nqp::if(
nqp::iseq_i($elems,0),
True,
nqp::stmts(
(my $amap := nqp::getattr(nqp::decont(a),Map,'$!storage')),
(my $bmap := nqp::getattr(nqp::decont(b),Map,'$!storage')),
(my $iter := nqp::iterator($amap)),
nqp::while(
$iter,
nqp::unless(
(nqp::existskey(
$bmap,my str $key = nqp::iterkey_s(nqp::shift($iter))
) && nqp::atkey($amap,$key) eqv nqp::atkey($bmap,$key)),
return False
nqp::eqaddr(a.WHAT,b.WHAT),
nqp::if(
nqp::iseq_i((my int $elems = a.elems),b.elems),
nqp::unless(
nqp::iseq_i($elems,0),
nqp::stmts(
(my $amap := nqp::getattr(nqp::decont(a),Map,'$!storage')),
(my $bmap := nqp::getattr(nqp::decont(b),Map,'$!storage')),
(my $iter := nqp::iterator($amap)),
nqp::while(
$iter
&& nqp::existskey($bmap,
my str $key = nqp::iterkey_s(nqp::shift($iter)))
&& nqp::atkey($amap,$key) eqv nqp::atkey($bmap,$key),
($elems = nqp::sub_i($elems,1))
),
nqp::iseq_i($elems,0) # checked all, so ok
)
),
True
)
)
),
False
)
)
)
}
Expand Down
51 changes: 34 additions & 17 deletions src/core/Mu.pm
Expand Up @@ -821,26 +821,43 @@ multi sub infix:<=:=>(Mu \a, Mu \b) {

proto sub infix:<eqv>(Any $?, Any $?) is pure { * }
multi sub infix:<eqv>($?) { Bool::True }
multi sub infix:<eqv>(Any $a, Any $b) {
# Last ditch snapshot semantics. We shouldn't come here too often, so
# please do not change this to be faster but wronger. (Instead, add
# specialized multis for datatypes that can be tested piecemeal.)
$a.WHAT === $b.WHAT and $a.perl eq $b.perl;

# Last ditch snapshot semantics. We shouldn't come here too often, so
# please do not change this to be faster but wronger. (Instead, add
# specialized multis for datatypes that can be tested piecemeal.)
multi sub infix:<eqv>(Any:U \a, Any:U \b) {
nqp::p6bool(nqp::eqaddr(nqp::decont(a),nqp::decont(b)))
}
multi sub infix:<eqv>(Any:D \a, Any:U \b) { False }
multi sub infix:<eqv>(Any:U \a, Any:D \b) { False }
multi sub infix:<eqv>(Any:D \a, Any:D \b) {
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_s(a.perl,b.perl))
)
}

multi sub infix:<eqv>(@a, @b) {
if @a =:= @b {
True
}
elsif @a.WHAT =:= @b.WHAT && (my int $n = @a.elems) == @b.elems {
my int $i = -1;
return False unless @a.AT-POS($i) eqv @b.AT-POS($i)
while nqp::islt_i(++$i,$n);
True
}
else {
False
}
nqp::p6bool(
nqp::unless(
nqp::eqaddr(@a,@b), # identity
nqp::if(
nqp::eqaddr(@a.WHAT,@b.WHAT), # same type
nqp::if(
nqp::iseq_i((my int $elems = @a.elems),@b.elems), # same # elems
nqp::stmts(
(my int $i = -1),
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems) # not exhausted
&& @a.AT-POS($i) eqv @b.AT-POS($i), # still same
nqp::null
),
nqp::iseq_i($i,$elems) # exhausted = success!
)
)
)
)
)
}

sub DUMP(|args (*@args, :$indent-step = 4, :%ctx?)) {
Expand Down
4 changes: 3 additions & 1 deletion src/core/Numeric.pm
Expand Up @@ -30,7 +30,9 @@ my role Numeric {
}

multi sub infix:<eqv>(Numeric:D \a, Numeric:D \b) {
nqp::p6bool(a =:= b || (a.WHAT =:= b.WHAT && a == b)) # RT #127951
nqp::p6bool(
nqp::eqaddr(a,b) || (nqp::eqaddr(a.WHAT,b.WHAT) && a == b) # RT #127951
)
}

## arithmetic operators
Expand Down
7 changes: 6 additions & 1 deletion src/core/Pair.pm
Expand Up @@ -84,7 +84,12 @@ my class Pair does Associative {
}

multi sub infix:<eqv>(Pair:D \a, Pair:D \b) {
a =:= b || (a.WHAT =:= b.WHAT && a.key eqv b.key && a.value eqv b.value)
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT)
&& a.key eqv b.key
&& a.value eqv b.value)
)
}

multi sub infix:<cmp>(Pair:D \a, Pair:D \b) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/Parameter.pm
Expand Up @@ -383,7 +383,7 @@ my class Parameter { # declared in BOOTSTRAP
}
}

multi sub infix:<eqv>(Parameter \a, Parameter \b) {
multi sub infix:<eqv>(Parameter:D \a, Parameter:D \b) {

# we're us
return True if a =:= b;
Expand Down
4 changes: 3 additions & 1 deletion src/core/Promise.pm
Expand Up @@ -221,7 +221,9 @@ my class Promise {
}

multi sub infix:<eqv>(Promise:D \a, Promise:D \b) {
a =:= b || a.result eqv b.result
nqp::p6bool(
nqp::eqaddr(a,b) || a.result eqv b.result
)
}

# vim: ft=perl6 expandtab sw=4
20 changes: 14 additions & 6 deletions src/core/Range.pm
Expand Up @@ -675,12 +675,20 @@ sub prefix:<^>($max) is pure {
}

multi sub infix:<eqv>(Range:D \a, Range:D \b) {
a =:= b
|| (a.WHAT =:= b.WHAT
&& a.min eqv b.min
&& a.max eqv b.max
&& a.excludes-min eqv b.excludes-min
&& a.excludes-max eqv b.excludes-max)
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT)
&& a.min eqv b.min
&& a.max eqv b.max
&& nqp::iseq_i(
nqp::getattr_i(nqp::decont(a),Range,'$!excludes-min'),
nqp::getattr_i(nqp::decont(b),Range,'$!excludes-min')
)
&& nqp::iseq_i(
nqp::getattr_i(nqp::decont(a),Range,'$!excludes-max'),
nqp::getattr_i(nqp::decont(b),Range,'$!excludes-max')
))
)
}

multi sub infix:<+>(Range:D \a, Real:D \b) { a.clone-with-op(&[+], b) }
Expand Down
50 changes: 31 additions & 19 deletions src/core/Seq.pm
Expand Up @@ -492,25 +492,37 @@ sub GATHER(&block) {
}

multi sub infix:<eqv>(Seq:D \a, Seq:D \b) {

# we're us
return True if a =:= b;

# not same container type
return False unless a.WHAT =:= b.WHAT;

my \ia := a.iterator;
my \ib := b.iterator;
my $va;
my $vb;

# same until a-list exhausted
return False
if ($vb := ib.pull-one) =:= IterationEnd || !($va eqv $vb)
until ($va := ia.pull-one) =:= IterationEnd;

# b-list also exhausted?
ib.pull-one =:= IterationEnd
nqp::p6bool(
nqp::unless(
nqp::eqaddr(a,b),
nqp::if(
nqp::eqaddr(a.WHAT,b.WHAT),
nqp::if(
nqp::iseq_i(
(my \ia := a.iterator).is-lazy,
(my \ib := b.iterator).is-lazy
),
nqp::if(
ia.is-lazy,
(die "Cannot eqv lazy Sequences"),
nqp::stmts(
nqp::until(
nqp::stmts(
(my \pa := ia.pull-one),
(my \pb := ib.pull-one),
nqp::eqaddr(pa,IterationEnd)
|| nqp::eqaddr(pb,IterationEnd)
|| nqp::not_i(pa eqv pb)
),
nqp::null
),
nqp::eqaddr(pa,pb) # exhausted if both IterationEnd
)
)
)
)
)
)
}

# vim: ft=perl6 expandtab sw=4
2 changes: 1 addition & 1 deletion src/core/Signature.pm
Expand Up @@ -134,7 +134,7 @@ my class Signature { # declared in BOOTSTRAP
}
}

multi sub infix:<eqv>(Signature \a, Signature \b) {
multi sub infix:<eqv>(Signature:D \a, Signature:D \b) {

# we're us
return True if a =:= b;
Expand Down
9 changes: 9 additions & 0 deletions src/core/Str.pm
Expand Up @@ -2815,6 +2815,15 @@ sub substr-rw(\what, \start, $want?) is rw {
)
}

multi sub infix:<eqv>(Str:D \a, Str:D \b) {
nqp::p6bool(
nqp::unless(
nqp::eqaddr(a,b),
nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_s(a,b)
)
)
}

proto sub samemark(|) {*}
multi sub samemark($s, $pat) { $s.samemark($pat) }

Expand Down
7 changes: 6 additions & 1 deletion src/core/Stringy.pm
Expand Up @@ -3,7 +3,12 @@ my class X::NYI { ... }
my role Stringy { }

multi sub infix:<eqv>(Stringy:D \a, Stringy:D \b) {
?(a =:= b || (a.WHAT =:= b.WHAT && (a cmp b) == 0)) # XXX RT #128092
nqp::p6bool(
nqp::unless(
nqp::eqaddr(a,b),
nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_i(a cmp b,0) # XXX RT #128092
)
)
}

proto sub prefix:<~>($) is pure { * }
Expand Down
9 changes: 8 additions & 1 deletion src/core/Version.pm
Expand Up @@ -115,7 +115,14 @@ class Version {


multi sub infix:<eqv>(Version:D \a, Version:D \b) {
a =:= b || (a.WHAT =:= b.WHAT && a.Str eq b.Str)
nqp::p6bool(
nqp::eqaddr(a,b)
|| (nqp::eqaddr(a.WHAT,b.WHAT)
&& nqp::iseq_s(
nqp::getattr_s(a,Version,'$!string'),
nqp::getattr_s(b,Version,'$!string')
))
)
}

multi sub infix:<cmp>(Version:D \a, Version:D \b) {
Expand Down
16 changes: 13 additions & 3 deletions src/core/allomorphs.pm
Expand Up @@ -65,19 +65,29 @@ my class ComplexStr is Complex is Str {
multi sub infix:<cmp>(IntStr:D $a, IntStr:D $b) {
$a.Int cmp $b.Int || $a.Str cmp $b.Str
}

multi sub infix:<cmp>(RatStr:D $a, RatStr:D $b) {
$a.Rat cmp $b.Rat || $a.Str cmp $b.Str
}

multi sub infix:<cmp>(NumStr:D $a, NumStr:D $b) {
$a.Num cmp $b.Num || $a.Str cmp $b.Str
}

multi sub infix:<cmp>(ComplexStr:D $a, ComplexStr:D $b) {
$a.Complex cmp $b.Complex || $a.Str cmp $b.Str
}

multi sub infix:<eqv>(IntStr:D $a, IntStr:D $b) {
$a.Int eqv $b.Int || $a.Str eqv $b.Str
}
multi sub infix:<eqv>(RatStr:D $a, RatStr:D $b) {
$a.Rat eqv $b.Rat || $a.Str eqv $b.Str
}
multi sub infix:<eqv>(NumStr:D $a, NumStr:D $b) {
$a.Num eqv $b.Num || $a.Str eqv $b.Str
}
multi sub infix:<eqv>(ComplexStr:D $a, ComplexStr:D $b) {
$a.Complex eqv $b.Complex || $a.Str eqv $b.Str
}

multi sub val(*@maybevals) {
@maybevals.list.map({ val($_) }).eager;
}
Expand Down

0 comments on commit bc7fcc6

Please sign in to comment.