Skip to content

Commit 36c494b

Browse files
committed
simple caching
1 parent c50d6cd commit 36c494b

File tree

1 file changed

+44
-16
lines changed

1 file changed

+44
-16
lines changed

Modules/_datetimemodule.c

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ typedef struct {
5252

5353
/* The interned Unix epoch datetime instance */
5454
PyObject *epoch;
55+
56+
PyObject *time_time;
57+
PyObject *time_struct_time;
58+
PyObject *time_strftime;
5559
} datetime_state;
5660

5761
/* The module has a fixed number of static objects, due to being exposed
@@ -1879,10 +1883,12 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
18791883
assert(object && format && timetuple);
18801884
assert(PyUnicode_Check(format));
18811885

1882-
PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
1883-
if (strftime == NULL) {
1886+
PyObject *current_mod = NULL;
1887+
datetime_state *st = GET_CURRENT_STATE(current_mod);
1888+
if (st == NULL) {
18841889
return NULL;
18851890
}
1891+
PyObject *strftime = st->time_strftime;
18861892

18871893
/* Scan the input format, looking for %z/%Z/%f escapes, building
18881894
* a new format. Since computing the replacements for those codes
@@ -2042,7 +2048,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
20422048
Py_XDECREF(zreplacement);
20432049
Py_XDECREF(colonzreplacement);
20442050
Py_XDECREF(Zreplacement);
2045-
Py_XDECREF(strftime);
2051+
RELEASE_CURRENT_STATE(st, current_mod);
20462052
return result;
20472053

20482054
Error:
@@ -2059,13 +2065,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
20592065
static PyObject *
20602066
time_time(void)
20612067
{
2062-
PyObject *result = NULL;
2063-
PyObject *time = PyImport_ImportModuleAttrString("time", "time");
2064-
2065-
if (time != NULL) {
2066-
result = PyObject_CallNoArgs(time);
2067-
Py_DECREF(time);
2068+
PyObject *current_mod = NULL;
2069+
datetime_state *st = GET_CURRENT_STATE(current_mod);
2070+
if (st == NULL) {
2071+
return NULL;
20682072
}
2073+
PyObject *result = PyObject_CallNoArgs(st->time_time);
2074+
RELEASE_CURRENT_STATE(st, current_mod);
20692075
return result;
20702076
}
20712077

@@ -2075,21 +2081,20 @@ time_time(void)
20752081
static PyObject *
20762082
build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
20772083
{
2078-
PyObject *struct_time;
2079-
PyObject *result;
2080-
2081-
struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
2082-
if (struct_time == NULL) {
2084+
PyObject *current_mod = NULL;
2085+
datetime_state *st = GET_CURRENT_STATE(current_mod);
2086+
if (st == NULL) {
20832087
return NULL;
20842088
}
20852089

2086-
result = PyObject_CallFunction(struct_time, "((iiiiiiiii))",
2090+
PyObject *result = PyObject_CallFunction(st->time_struct_time,
2091+
"((iiiiiiiii))",
20872092
y, m, d,
20882093
hh, mm, ss,
20892094
weekday(y, m, d),
20902095
days_before_month(y, m) + d,
20912096
dstflag);
2092-
Py_DECREF(struct_time);
2097+
RELEASE_CURRENT_STATE(st, current_mod);
20932098
return result;
20942099
}
20952100

@@ -7414,6 +7419,9 @@ init_state(datetime_state *st, PyObject *module, PyObject *old_module)
74147419
.us_per_week = Py_NewRef(st_old->us_per_week),
74157420
.seconds_per_day = Py_NewRef(st_old->seconds_per_day),
74167421
.epoch = Py_NewRef(st_old->epoch),
7422+
.time_time = Py_NewRef(st_old->time_time),
7423+
.time_struct_time = Py_NewRef(st_old->time_struct_time),
7424+
.time_strftime = Py_NewRef(st_old->time_strftime),
74177425
};
74187426
return 0;
74197427
}
@@ -7458,6 +7466,19 @@ init_state(datetime_state *st, PyObject *module, PyObject *old_module)
74587466
return -1;
74597467
}
74607468

7469+
st->time_time = PyImport_ImportModuleAttrString("time", "time");
7470+
if (st->time_time == NULL) {
7471+
return -1;
7472+
}
7473+
st->time_struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
7474+
if (st->time_struct_time == NULL) {
7475+
return -1;
7476+
}
7477+
st->time_strftime = PyImport_ImportModuleAttrString("time", "strftime");
7478+
if (st->time_strftime == NULL) {
7479+
return -1;
7480+
}
7481+
74617482
return 0;
74627483
}
74637484

@@ -7467,6 +7488,10 @@ traverse_state(datetime_state *st, visitproc visit, void *arg)
74677488
/* heap types */
74687489
Py_VISIT(st->isocalendar_date_type);
74697490

7491+
Py_VISIT(st->time_time);
7492+
Py_VISIT(st->time_struct_time);
7493+
Py_VISIT(st->time_strftime);
7494+
74707495
return 0;
74717496
}
74727497

@@ -7482,6 +7507,9 @@ clear_state(datetime_state *st)
74827507
Py_CLEAR(st->us_per_week);
74837508
Py_CLEAR(st->seconds_per_day);
74847509
Py_CLEAR(st->epoch);
7510+
Py_CLEAR(st->time_time);
7511+
Py_CLEAR(st->time_struct_time);
7512+
Py_CLEAR(st->time_strftime);
74857513
return 0;
74867514
}
74877515

0 commit comments

Comments
 (0)