11

I was debugging a function speed, and discovered that the time bottleneck was in DatePlus. I tried to change to DayPlus and get a even worse result.

Here are my time tests:

myDatePlus = DateList[AbsoluteTime[#1] + 86400*#2][[ ;; 3]] &;
n = 10^4;
t1 = (Table[myDatePlus[{2015, 3, 100}, 365], {i, 0, n}]; // 
        AbsoluteTiming // First)
t2 = (Table[DatePlus[{2015, 3, 100}, 365], {i, 0, n}]; // 
        AbsoluteTiming // First)
t3 = (Table[Normal[DayPlus[{2015, 3, 100}, 365]][[ ;; 3]], {i, 0, n}]; //
        AbsoluteTiming // First)

N[t2/t1] N[t3/t1]

>   0.068  (*t1*)
>   3.957  (*t2*)
>  13.428  (*t3*)

> 58.19 (t2/t1) > 197.47 (t3/t1)

Can someone confirm it? Is t1 the best way to do it in current Mathematica version? (V10.0.2)

Murta
  • 26,275
  • 6
  • 76
  • 166
  • 6
    Many of the built-in date functions are very slow. For bulk data I usually use my own functions. – Sjoerd C. de Vries Mar 27 '15 at 07:11
  • 1
    Have you seen some of the past questions / answers on this topic, involving Java, like this discussion for instance? I found that for date functions, and when you need to perform operations in a bulk, this approach works well. – Leonid Shifrin Mar 27 '15 at 11:21
  • 1
    I used to send comparative benchmarks to Wolfram with every Mathematica release, pointing out how slow their date functions were compared to other interpreted languages. They don't seem to view this as a priority, but perhaps if more of us were to complain they would tackle the problem. – Michael Stern Apr 15 '16 at 22:49

1 Answers1

4

This question deserves an answer and even better, the answer is also good news as much has improved by now.

$Version
(* 14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023) *)

With[ { myDatePlus = DateList[ AbsoluteTime[#1] + 86400. * #2 ]&, n = 10^4 }, Module[ {t1,t2,t3, performance}, t1 := Inactivate @ Table[ myDatePlus[ {2024, 2, 7}, 365 ], {i, n}]; t2 := Inactivate @ Table[ DatePlus[ {2024, 2, 7}, 365 ], {i,n} ]; t3 := Inactivate @ Table[ DayPlus[ {2024, 2, 7}, 365 ], {i, n} ]; performance = Map[ Activate /* AbsoluteTiming /* First, { t1, t2, t3 } ]; performance // Association[ "AbsoluteTime" -> #[[1]], "DatePlus" -> #[[2]], "DayPlus" -> #[[3]], "DatePlus : AbsoluteTime" -> #[[2]]/#[[1]], "DayPlus : AbsoluteTime" -> #[[3]]/#[[1]] ]& // Dataset ] ]

Dataset Output

The main culprit for the slower performance of the DayPlus function seems to be DateObject and its overhead being used. The DatePlus function allows for much more flexibility.

If we replace {2024, 2, 7} with Today as to start with DateObject as input for all three functions, it is nice to note that DatePlus remains very fast.

Result using Today as input

enter image description here

Remarks

  1. I did not bother to use [[ ;; 3]] as to "crop" the DateList format to { y, m, d } as this will not change the result significantly.

  2. Note, that Normal has been modified since v10.0.2 and—as of v14—will now not give a DateList when applied to a DateObject. Instead, one would need to apply DateList itself, e.g., DateList[ DateObject[...] ].

gwr
  • 13,452
  • 2
  • 47
  • 78