summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorItamar Ostricher <itamarost@gmail.com>2023-04-29 15:20:09 (GMT)
committerGitHub <noreply@github.com>2023-04-29 15:20:09 (GMT)
commit85c7bf5bcec07beea6064976e6199195cd34329d (patch)
tree5515f9539c36a6ac1e3e231a1a297e403d9d6928 /Modules
parentfbf3596c3edadd03b5a8c659e9f27a09e5d1a051 (diff)
downloadcpython-85c7bf5bcec07beea6064976e6199195cd34329d.zip
cpython-85c7bf5bcec07beea6064976e6199195cd34329d.tar.gz
cpython-85c7bf5bcec07beea6064976e6199195cd34329d.tar.bz2
gh-103793: Defer formatting task name (#103767)
The default task name is "Task-<counter>" (if no name is passed in during Task creation). This is initialized in `Task.__init__` (C impl) using string formatting, which can be quite slow. Actually using the task name in real world code is not very common, so this is wasted init. Let's defer this string formatting to the first time the name is read (in `get_name` impl), so we don't need to pay the string formatting cost if the task name is never read. We don't change the order in which tasks are assigned numbers (if they are) -- the number is set on task creation, as a PyLong instead of a formatted string. Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_asynciomodule.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index 2476dca..82dbc08 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -2069,8 +2069,10 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop,
Py_XSETREF(self->task_coro, coro);
if (name == Py_None) {
- name = PyUnicode_FromFormat("Task-%" PRIu64,
- ++state->task_name_counter);
+ // optimization: defer task name formatting
+ // store the task counter as PyLong in the name
+ // for deferred formatting in get_name
+ name = PyLong_FromUnsignedLongLong(++state->task_name_counter);
} else if (!PyUnicode_CheckExact(name)) {
name = PyObject_Str(name);
} else {
@@ -2449,6 +2451,13 @@ _asyncio_Task_get_name_impl(TaskObj *self)
/*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/
{
if (self->task_name) {
+ if (PyLong_CheckExact(self->task_name)) {
+ PyObject *name = PyUnicode_FromFormat("Task-%S", self->task_name);
+ if (name == NULL) {
+ return NULL;
+ }
+ Py_SETREF(self->task_name, name);
+ }
return Py_NewRef(self->task_name);
}