Skip to content

Commit fc3e22a

Browse files
gh-88473: Implement fast path in date.today() for date types (#130980)
Co-authored-by: Bénédikt Tran <[email protected]>
1 parent d61dda5 commit fc3e22a

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Implement a fast path for :class:`datetime.date` objects in :func:`datetime.date.today`
2+
which results in a 5x performance gain while proper subclasses retain their
3+
previous performance.

Modules/_datetimemodule.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3291,19 +3291,31 @@ static PyObject *
32913291
datetime_date_today_impl(PyTypeObject *type)
32923292
/*[clinic end generated code: output=d5474697df6b251c input=21688afa289c0a06]*/
32933293
{
3294-
PyObject *time;
3295-
PyObject *result;
3296-
time = time_time();
3297-
if (time == NULL)
3294+
/* Use C implementation to boost performance for date type */
3295+
if (type == &PyDateTime_DateType) {
3296+
struct tm tm;
3297+
time_t t;
3298+
time(&t);
3299+
3300+
if (_PyTime_localtime(t, &tm) != 0) {
3301+
return NULL;
3302+
}
3303+
3304+
return new_date_ex(tm.tm_year + 1900,
3305+
tm.tm_mon + 1,
3306+
tm.tm_mday,
3307+
type);
3308+
}
3309+
3310+
PyObject *time = time_time();
3311+
if (time == NULL) {
32983312
return NULL;
3313+
}
32993314

3300-
/* Note well: today() is a class method, so this may not call
3301-
* date.fromtimestamp. For example, it may call
3302-
* datetime.fromtimestamp. That's why we need all the accuracy
3303-
* time.time() delivers; if someone were gonzo about optimization,
3304-
* date.today() could get away with plain C time().
3315+
/* Note well: since today() is a class method, it may not call
3316+
* date.fromtimestamp, e.g., it may call datetime.fromtimestamp.
33053317
*/
3306-
result = PyObject_CallMethodOneArg((PyObject*)type, &_Py_ID(fromtimestamp), time);
3318+
PyObject *result = PyObject_CallMethodOneArg((PyObject*)type, &_Py_ID(fromtimestamp), time);
33073319
Py_DECREF(time);
33083320
return result;
33093321
}

0 commit comments

Comments
 (0)