Skip to content

Commit

Permalink
Improve array assignment inlinability
Browse files Browse the repository at this point in the history
Prior to this, the ASSIGN-POS method was too large to inline on MoarVM,
but it's really quite helpful for performance if it does inline. Since
MoarVM doesn't factor in the size of nested inlines, however, then it's
possible to get below the inline limit by splitting some of the code out
into a private method, as done by this commit.
  • Loading branch information
jnthn committed Sep 27, 2018
1 parent 4a96805 commit 8bd3e50
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions src/core/Array.pm6
Expand Up @@ -507,23 +507,27 @@ my class Array { # declared in BOOTSTRAP

# because this is a very hot path, we copied the code from the int candidate
multi method ASSIGN-POS(Array:D: Int:D $pos, Mu \assignee) is raw {
my \reified := nqp::getattr(self,List,'$!reified');
my \assignee_decont := nqp::decont(assignee);
my int $ipos = $pos;
nqp::isge_i($ipos, 0) && nqp::isconcrete(reified) &&
nqp::isge_i($pos, 0) && nqp::isconcrete(nqp::getattr(self,List,'$!reified')) &&
nqp::not_i(nqp::isconcrete(nqp::getattr(self,List,'$!todo')))
?? nqp::stmts(
(nqp::p6assign(
nqp::ifnull(
nqp::atpos(reified, $ipos),
nqp::bindpos(reified, $ipos,
nqp::p6bindattrinvres(nqp::create(Scalar), Scalar, '$!descriptor', $!descriptor))),
assignee_decont)),
assignee_decont)
?? self!ASSIGN_POS_FAST_PATH($pos, assignee_decont)
!! self!ASSIGN_POS_SLOW_PATH($pos, assignee_decont)
}

method !ASSIGN_POS_SLOW_PATH(Array:D: Int:D $pos, Mu \assignee) {
method !ASSIGN_POS_FAST_PATH(Array:D: Int:D $pos, Mu \assignee_decont) is raw {
my \reified := nqp::getattr(self,List,'$!reified');
my int $ipos = $pos;
nqp::stmts(
nqp::p6assign(
nqp::ifnull(
nqp::atpos(reified, $ipos),
nqp::bindpos(reified, $ipos,
nqp::p6bindattrinvres(nqp::create(Scalar), Scalar, '$!descriptor', $!descriptor))),
assignee_decont),
assignee_decont)
}

method !ASSIGN_POS_SLOW_PATH(Array:D: Int:D $pos, Mu \assignee) is raw {
nqp::if(
nqp::islt_i($pos,0),
self!INDEX_OOR($pos),
Expand Down

2 comments on commit 8bd3e50

@lizmat
Copy link
Contributor

@lizmat lizmat commented on 8bd3e50 Sep 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oddly enough, if I do the same change to the int $pos candidate, then it becomes slower:

for ^10_000 -> int $_ { my @a; for ^1000 -> int $_ { @a[$_] = 42 } }   # 1.840 -> 2.273

So I haven't done the int $pos candidate.

@lizmat
Copy link
Contributor

@lizmat lizmat commented on 8bd3e50 Sep 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I decided to revert this commit and see if how much the improvement was. In fact it wasn't :-(

for ^10_000 -> int $_ { my @a; for ^1000 -> Int $_ { @a[$_] = 42 } }  # 2.299 -> 2.045

This was on MacOS. I wonder if that makes a difference. I could --profile the old version, but profiling the new version dies with:

This type (Mu) does not support positional operations

:-(

Please sign in to comment.