It has been noticed on several occasions that DayOfWeek
function is rather slow when applied to a large list of dates, e.g. in this recent question. What faster alternatives do we have in such situations?
Answer
Just a literal implementation of a formula for the day of the week:
Clear[dow];
dow[{year_, month_, day_, _ : 0, _ : 0, _ : 0}] :=
Module[{Y = If[month == 1 || month == 2, year - 1, year],
m = Mod[month + 9, 12] + 1, y, c,
s = {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}},
y = Mod[Y, 100];
c = Quotient[Y, 100];
s[[Mod[day + Floor[2.6 m - 0.2] + y + Quotient[y, 4] + Quotient[c, 4] - 2 c, 7] + 1]]];
Seems to give a 5-fold speed increase:
d = RandomDates[100000];
DayOfWeek /@ d // Short // AbsoluteTiming
dow /@ d // Short // AbsoluteTiming
{19.5781250,{Thursday,Thursday,Sunday,Friday,<<99992>>,Tuesday,Saturday,Saturday,Thursday}}
{3.7968750,{Thursday,Thursday,Sunday,Friday,<<99992>>,Tuesday,Saturday,Saturday,Thursday}}
Addition
Your function is readily compilable:
dowc = Compile[{{year, _Integer}, {month, _Integer}, {day, _Integer}},
Module[
{Y, m, y, c, s},
Y = If[month == 1 || month==2, year-1, year];
m = Mod[month + 9, 12] + 1;
y = Mod[Y, 100]; c = Quotient[Y, 100];
Mod[day + Floor[2.6 m-0.2] + y + Quotient[y, 4] + Quotient[c, 4]-2 c,7]+1
],
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
Parallelization -> True
];
In[286]:= dowc @@@ d[[All, 1 ;; 3]] // Short // AbsoluteTiming
Out[286]= {0.136741,{6,4,5,2,4,5,3,7,<<99984>>,5,4,2,4,3,2,5,6}}
Comments
Post a Comment