Skip to content

Commit

Permalink
Make Any.sort(&by) about 40% faster
Browse files Browse the repository at this point in the history
- for the 2-arg case
- using the new R:I.MERGESORT-REIFIED-LIST-WITH logic
- non-2arg case still handled by old code
  • Loading branch information
lizmat committed Dec 25, 2016
1 parent c43f625 commit 1374fcf
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/core/Any-iterable-methods.pm
Expand Up @@ -1456,22 +1456,41 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"
multi method sort() {
nqp::if(
nqp::eqaddr(
self.iterator.push-until-lazy(my $values := IterationBuffer.new),
self.iterator.push-until-lazy(my $list := IterationBuffer.new),
IterationEnd
),
Rakudo::Internals.MERGESORT-REIFIED-LIST(
nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$values)
nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$list)
),
X::Cannot::Lazy.new(:action<sort>).throw
)
}
multi method sort(&by) is nodal {

# Obtain all the things to sort.
my \iter = self.iterator;
my \sort-buffer = IterationBuffer.new;
X::Cannot::Lazy.new(:action<sort>).throw
unless iter.push-until-lazy(sort-buffer) =:= IterationEnd;
multi method sort(&by) {
nqp::stmts(
nqp::unless(
nqp::eqaddr(
self.iterator.push-until-lazy(my $list := IterationBuffer.new),
IterationEnd
),
X::Cannot::Lazy.new(:action<sort>).throw
),
nqp::if(
nqp::eqaddr(&by,&infix:<cmp>),
Rakudo::Internals.MERGESORT-REIFIED-LIST(
nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$list)
),
nqp::if(
nqp::islt_i((my int $count = &by.count),2),
self!oldsort($list,&by),
Rakudo::Internals.MERGESORT-REIFIED-LIST-WITH(
nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$list),
&by
)
)
)
)
}
method !oldsort(\sort-buffer,&by) {

# Instead of sorting elements directly, we sort a list of
# indices from 0..^$list.elems, then use that list as
Expand Down

0 comments on commit 1374fcf

Please sign in to comment.