| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent fbf3596 commit 85c7bf5
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -610,6 +610,9 @@ Optimizations | |||
| 610 | 610 | replacement strings containing group references by 2--3 times. | |
| 611 | 611 | (Contributed by Serhiy Storchaka in :gh:`91524`.) | |
| 612 | 612 | ||
| 613 | + * Speed up :class:`asyncio.Task` creation by deferring expensive string formatting. | ||
| 614 | + (Contributed by Itamar O in :gh:`103793`.) | ||
| 615 | + | ||
| 613 | 616 | ||
| 614 | 617 | CPython bytecode changes | |
| 615 | 618 | ======================== | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -399,6 +399,18 @@ async def notmuch(): | |||
| 399 | 399 | self.loop.run_until_complete(t1) | |
| 400 | 400 | self.loop.run_until_complete(t2) | |
| 401 | 401 | ||
| 402 | + def test_task_set_name_pylong(self): | ||
| 403 | + # test that setting the task name to a PyLong explicitly doesn't | ||
| 404 | + # incorrectly trigger the deferred name formatting logic | ||
| 405 | + async def notmuch(): | ||
| 406 | + return 123 | ||
| 407 | + | ||
| 408 | + t = self.new_task(self.loop, notmuch(), name=987654321) | ||
| 409 | + self.assertEqual(t.get_name(), '987654321') | ||
| 410 | + t.set_name(123456789) | ||
| 411 | + self.assertEqual(t.get_name(), '123456789') | ||
| 412 | + self.loop.run_until_complete(t) | ||
| 413 | + | ||
| 402 | 414 | def test_task_repr_name_not_str(self): | |
| 403 | 415 | async def notmuch(): | |
| 404 | 416 | return 123 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Optimized asyncio Task creation by deferring expensive string formatting | ||
| 2 | + (task name generation) from Task creation to the first time ``get_name`` is | ||
| 3 | + called. This makes asyncio benchmarks up to 5% faster. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2069,8 +2069,10 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, | |||
| 2069 | 2069 | Py_XSETREF(self->task_coro, coro); | |
| 2070 | 2070 | ||
| 2071 | 2071 | if (name == Py_None) { | |
| 2072 | - name = PyUnicode_FromFormat("Task-%" PRIu64, | ||
| 2073 | - ++state->task_name_counter); | ||
| 2072 | + // optimization: defer task name formatting | ||
| 2073 | + // store the task counter as PyLong in the name | ||
| 2074 | + // for deferred formatting in get_name | ||
| 2075 | + name = PyLong_FromUnsignedLongLong(++state->task_name_counter); | ||
| 2074 | 2076 | } else if (!PyUnicode_CheckExact(name)) { | |
| 2075 | 2077 | name = PyObject_Str(name); | |
| 2076 | 2078 | } else { | |
@@ -2449,6 +2451,13 @@ _asyncio_Task_get_name_impl(TaskObj *self) | |||
| 2449 | 2451 | /*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/ | |
| 2450 | 2452 | { | |
| 2451 | 2453 | if (self->task_name) { | |
| 2454 | + if (PyLong_CheckExact(self->task_name)) { | ||
| 2455 | + PyObject *name = PyUnicode_FromFormat("Task-%S", self->task_name); | ||
| 2456 | + if (name == NULL) { | ||
| 2457 | + return NULL; | ||
| 2458 | + } | ||
| 2459 | + Py_SETREF(self->task_name, name); | ||
| 2460 | + } | ||
| 2452 | 2461 | return Py_NewRef(self->task_name); | |
| 2453 | 2462 | } | |
| 2454 | 2463 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments