From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 16 Sep 2025 09:28:54 +0000 (+0100) Subject: gh-88473: Implement fast path in date.today() for date types (#130980) X-Git-Tag: v3.15.0a1~337 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fc3e22a06c9b7c93ee379b5554a40a275745e15f;p=thirdparty%2FPython%2Fcpython.git gh-88473: Implement fast path in date.today() for date types (#130980) Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- diff --git a/Misc/NEWS.d/next/Library/2025-03-08-17-07-00.gh-issue-88473.qg23g8.rst b/Misc/NEWS.d/next/Library/2025-03-08-17-07-00.gh-issue-88473.qg23g8.rst new file mode 100644 index 000000000000..f38ec8ef8104 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-08-17-07-00.gh-issue-88473.qg23g8.rst @@ -0,0 +1,3 @@ +Implement a fast path for :class:`datetime.date` objects in :func:`datetime.date.today` +which results in a 5x performance gain while proper subclasses retain their +previous performance. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 329be68d5b82..12d316985fce 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -3291,19 +3291,31 @@ static PyObject * datetime_date_today_impl(PyTypeObject *type) /*[clinic end generated code: output=d5474697df6b251c input=21688afa289c0a06]*/ { - PyObject *time; - PyObject *result; - time = time_time(); - if (time == NULL) + /* Use C implementation to boost performance for date type */ + if (type == &PyDateTime_DateType) { + struct tm tm; + time_t t; + time(&t); + + if (_PyTime_localtime(t, &tm) != 0) { + return NULL; + } + + return new_date_ex(tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + type); + } + + PyObject *time = time_time(); + if (time == NULL) { return NULL; + } - /* Note well: today() is a class method, so this may not call - * date.fromtimestamp. For example, it may call - * datetime.fromtimestamp. That's why we need all the accuracy - * time.time() delivers; if someone were gonzo about optimization, - * date.today() could get away with plain C time(). + /* Note well: since today() is a class method, it may not call + * date.fromtimestamp, e.g., it may call datetime.fromtimestamp. */ - result = PyObject_CallMethodOneArg((PyObject*)type, &_Py_ID(fromtimestamp), time); + PyObject *result = PyObject_CallMethodOneArg((PyObject*)type, &_Py_ID(fromtimestamp), time); Py_DECREF(time); return result; }