Skip to content

Commit

Permalink
Make Cursor.MATCH about 10-15% faster
Browse files Browse the repository at this point in the history
By converting more of it to NQP ops and pulling some initial variable
declarations out of loops (reducing the number of call frames and
garbage collections).
  • Loading branch information
MasterDuke17 committed Dec 30, 2016
1 parent c0d8a45 commit 9eef565
Showing 1 changed file with 33 additions and 25 deletions.
58 changes: 33 additions & 25 deletions src/core/Cursor.pm
Expand Up @@ -41,30 +41,32 @@ my class Cursor does NQPCursorRole {
nqp::bindattr($match, Match, '$!CURSOR', self);
my Mu $list;
my Mu $hash := nqp::hash();
if $to >= $from {
if nqp::isge_i($to, $from) {
# For captures with lists, initialize the lists.
my $caplist := $NO_CAPS;
my $rxsub := nqp::getattr(self, Cursor, '$!regexsub');
my str $onlyname = '';
my int $namecount = 0;

if !nqp::isnull($rxsub) && nqp::defined($rxsub) {
if nqp::not_i(nqp::isnull($rxsub)) {
$caplist := nqp::can($rxsub, 'CAPS') ?? nqp::findmethod($rxsub, 'CAPS')($rxsub) !! nqp::null();
if !nqp::isnull($caplist) && nqp::istrue($caplist) {
if nqp::not_i(nqp::isnull($caplist)) && nqp::istrue($caplist) {
my $iter := nqp::iterator($caplist);
my $curcap;
my str $name;
while $iter {
my $curcap := nqp::shift($iter);
$namecount = $namecount + 1;
$curcap := nqp::shift($iter);
$namecount = nqp::add_i($namecount, 1);
#?if jvm
my Mu $curval := nqp::iterval($curcap);
if (nqp::isint($curval) && nqp::isge_i($curval, 2))
|| (nqp::isnum($curval) && nqp::p6box_n($curval) >= 2) {
|| (nqp::isnum($curval) && nqp::isge_n($curval, 2)) {
#?endif
#?if !jvm
if nqp::iterval($curcap) >= 2 {
#?endif
my str $name = nqp::iterkey_s($curcap);
$onlyname = $name if $namecount == 1;
$name = nqp::iterkey_s($curcap);
$onlyname = $name if nqp::iseq_i($namecount, 1);
nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0)
?? nqp::bindpos(
nqp::if(nqp::isconcrete($list), $list, ($list := nqp::list())),
Expand All @@ -77,11 +79,11 @@ my class Cursor does NQPCursorRole {

# Walk the Cursor stack and populate the Cursor.
my Mu $cs := nqp::getattr(self, Cursor, '$!cstack');
if nqp::isnull($cs) || !nqp::istrue($cs) {}
if nqp::isnull($cs) || nqp::not_i(nqp::istrue($cs)) {}
#?if !jvm
elsif !$caplist {}
elsif nqp::not_i(nqp::istrue($caplist)) {}
#?endif
elsif $namecount == 1 && $onlyname ne '' && nqp::eqat($onlyname,'$!',0) {
elsif nqp::iseq_i($namecount, 1) && nqp::isgt_i(nqp::chars($onlyname), 0) && nqp::eqat($onlyname, '$!', 0) {
# If there's only one destination, avoid repeated hash lookups
my int $cselems = nqp::elems($cs);
my int $csi = -1;
Expand All @@ -92,30 +94,34 @@ my class Cursor does NQPCursorRole {
?? nqp::atpos($list, $onlyname)
!! nqp::atkey($hash, $onlyname);

my $subcur;
my str $name;
while nqp::islt_i(++$csi,$cselems) {
my $subcur := nqp::atpos($cs, $csi);
my str $name = nqp::getattr_s($subcur, $?CLASS, '$!name');
$subcur := nqp::atpos($cs, $csi);
$name = nqp::getattr_s($subcur, $?CLASS, '$!name');
nqp::push($dest,$subcur.MATCH())
if !nqp::isnull_s($name) && nqp::defined($name);
if nqp::not_i(nqp::isnull_s($name));
}
}
else {
my int $cselems = nqp::elems($cs);
my int $csi = -1;
my $subcur;
my str $name;
while nqp::islt_i(++$csi,$cselems) {
my Mu $subcur := nqp::atpos($cs, $csi);
my str $name = nqp::getattr_s($subcur, $?CLASS, '$!name');
if !nqp::isnull_s($name) && nqp::defined($name) && $name ne '' {
$subcur := nqp::atpos($cs, $csi);
$name = nqp::getattr_s($subcur, $?CLASS, '$!name');
if nqp::not_i(nqp::isnull_s($name)) && nqp::isgt_i(nqp::chars($name), 0) {
my Mu $submatch := $subcur.MATCH;
if nqp::eqat($name, '$', 0) && ($name eq '$!from' || $name eq '$!to') {
if nqp::eqat($name, '$', 0) && (nqp::iseq_s($name, '$!from') || nqp::iseq_s($name, '$!to')) {
nqp::bindattr_i($match, Match, $name, $submatch.from);
}
elsif nqp::index($name, '=') < 0 {
elsif nqp::islt_i(nqp::index($name, '='), 0) {
my Mu $capval := nqp::atkey($caplist, $name);
#?if jvm
my int $needs_list = nqp::isconcrete($capval) &&
((nqp::isint($capval) && nqp::isge_i($capval, 2)) ||
(nqp::isnum($capval) && nqp::p6box_n($capval) >= 2));
(nqp::isnum($capval) && nqp::isge_n($capval, 2)));
#?endif
#?if !jvm
my int $needs_list = nqp::isconcrete($capval) && $capval >= 2;
Expand All @@ -135,16 +141,18 @@ my class Cursor does NQPCursorRole {
else {
my $names := nqp::split('=', $name);
my $iter := nqp::iterator($names);
my Mu $capval;
my int $needs_list;
while $iter {
my str $name = nqp::shift($iter);
my Mu $capval := nqp::atkey($caplist, $name);
$name = nqp::shift($iter);
$capval := nqp::atkey($caplist, $name);
#?if jvm
my int $needs_list = nqp::isconcrete($capval) &&
$needs_list = nqp::isconcrete($capval) &&
((nqp::isint($capval) && nqp::isge_i($capval, 2)) ||
(nqp::isnum($capval) && nqp::p6box_n($capval) >= 2));
(nqp::isnum($capval) && nqp::isge_n($capval, 2)));
#?endif
#?if !jvm
my int $needs_list = nqp::isconcrete($capval) && $capval >= 2;
$needs_list = nqp::isconcrete($capval) && $capval >= 2;
#?endif
if nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) {
$list := nqp::list() unless nqp::isconcrete($list);
Expand Down

0 comments on commit 9eef565

Please sign in to comment.