Skip to content

Commit

Permalink
Make Date.succ/pred and Date ± N about 3x as fast (usually)
Browse files Browse the repository at this point in the history
This should make iterating over a range of Dates or a loop with ++$date
about 3x as fast.  Optimization based on the observation that if only the
date value can change, we just need to clone the object and update the day
value.  Complicating factor could be the daycount attribute that also needs
updating if it is set.  If anything apart the day needs to change, then it
will fallback to the old logic, creating a new object using the daycount
attribute.
  • Loading branch information
lizmat committed Nov 11, 2018
1 parent bf3eb8e commit a11d599
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/core/Date.pm6
Expand Up @@ -163,11 +163,26 @@ my class Date does Dateish {
)
}

method new-from-diff(Date:D: Int:D $diff) {
nqp::isconcrete($!daycount)
?? nqp::stmts(
(my \new := nqp::clone(self)),
nqp::bindattr(new,Date,'$!day', $!day + $diff),
nqp::bindattr(new,Date,'$!daycount',$!daycount + $diff),
new
)
!! nqp::p6bindattrinvres(nqp::clone(self),Date,'$!day',$!day + $diff)
}

method succ(Date:D:) {
self.new-from-daycount(self.daycount + 1);
$!day < 28 && nqp::eqaddr(self.WHAT,Date)
?? self.new-from-diff(1)
!! self.new-from-daycount(self.daycount + 1)
}
method pred(Date:D:) {
self.new-from-daycount(self.daycount - 1);
$!day > 1 && nqp::eqaddr(self.WHAT,Date)
?? self.new-from-diff(-1)
!! self.new-from-daycount(self.daycount - 1)
}

multi method perl(Date:D:) {
Expand All @@ -184,13 +199,19 @@ my class Date does Dateish {
}

multi sub infix:<+>(Date:D $d, Int:D $x) {
Date.new-from-daycount($d.daycount + $x)
nqp::eqaddr($d.WHAT,Date) && $d.day + $x <= 28
?? $d.new-from-diff($x)
!! Date.new-from-daycount($d.daycount + $x)
}
multi sub infix:<+>(Int:D $x, Date:D $d) {
Date.new-from-daycount($d.daycount + $x)
nqp::eqaddr($d.WHAT,Date) && $d.day + $x <= 28
?? $d.new-from-diff($x)
!! Date.new-from-daycount($d.daycount + $x)
}
multi sub infix:<->(Date:D $d, Int:D $x) {
Date.new-from-daycount($d.daycount - $x)
nqp::eqaddr($d.WHAT,Date) && $d.day - $x > 0
?? $d.new-from-diff(-$x)
!! Date.new-from-daycount($d.daycount - $x)
}
multi sub infix:<->(Date:D $a, Date:D $b) {
$a.daycount - $b.daycount;
Expand Down

0 comments on commit a11d599

Please sign in to comment.