Skip to content
Permalink
Browse files

Make Date.succ/pred and Date ± N about 3x as fast (usually)

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 a11d599f4b8856d78ddea6540b09e7827776db49
Showing with 26 additions and 5 deletions.
  1. +26 −5 src/core/Date.pm6
@@ -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:) {
@@ -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;

0 comments on commit a11d599

Please sign in to comment.
You can’t perform that action at this time.