From f203450b8ccb06c05449a9e2b48647e530464634 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 20 Jun 2024 15:04:22 +0200 Subject: [PATCH] gh-119182: Use public PyUnicodeWriter API in union_repr() The public PyUnicodeWriter API enables overallocation by default and so is more efficient. Benchmark: python -m pyperf timeit \ -s 't = int | float | complex | str | bytes | bytearray' \ ' | memoryview | list | dict' \ 'str(t)' Result: 1.29 us +- 0.02 us -> 1.00 us +- 0.02 us: 1.29x faster --- Objects/unionobject.c | 54 ++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/Objects/unionobject.c b/Objects/unionobject.c index bf5605686f8df7..49b01e0aeb5d83 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -182,15 +182,14 @@ _Py_union_type_or(PyObject* self, PyObject* other) } static int -union_repr_item(_PyUnicodeWriter *writer, PyObject *p) +union_repr_item(PyUnicodeWriter *writer, PyObject *p) { PyObject *qualname = NULL; PyObject *module = NULL; - PyObject *r = NULL; int rc; if (p == (PyObject *)&_PyNone_Type) { - return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); + return PyUnicodeWriter_WriteUTF8(writer, "None", 4); } if ((rc = PyObject_HasAttrWithError(p, &_Py_ID(__origin__))) > 0 && @@ -200,17 +199,17 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) goto use_repr; } if (rc < 0) { - goto exit; + goto error; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { - goto exit; + goto error; } if (qualname == NULL) { goto use_repr; } if (PyObject_GetOptionalAttr(p, &_Py_ID(__module__), &module) < 0) { - goto exit; + goto error; } if (module == NULL || module == Py_None) { goto use_repr; @@ -221,24 +220,25 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) _PyUnicode_EqualToASCIIString(module, "builtins")) { // builtins don't need a module name - r = PyObject_Str(qualname); - goto exit; + rc = PyUnicodeWriter_WriteStr(writer, qualname); + goto done; } else { - r = PyUnicode_FromFormat("%S.%S", module, qualname); - goto exit; + rc = PyUnicodeWriter_Format(writer, "%S.%S", module, qualname); + goto done; } +error: + rc = -1; + goto done; + use_repr: - r = PyObject_Repr(p); -exit: + rc = PyUnicodeWriter_WriteRepr(writer, p); + goto done; + +done: Py_XDECREF(qualname); Py_XDECREF(module); - if (r == NULL) { - return -1; - } - rc = _PyUnicodeWriter_WriteStr(writer, r); - Py_DECREF(r); return rc; } @@ -248,20 +248,26 @@ union_repr(PyObject *self) unionobject *alias = (unionobject *)self; Py_ssize_t len = PyTuple_GET_SIZE(alias->args); - _PyUnicodeWriter writer; - _PyUnicodeWriter_Init(&writer); - for (Py_ssize_t i = 0; i < len; i++) { - if (i > 0 && _PyUnicodeWriter_WriteASCIIString(&writer, " | ", 3) < 0) { + // Shortest type name "int" (3 chars) + " | " (3 chars) separator + Py_ssize_t estimate = (len <= PY_SSIZE_T_MAX / 6) ? len * 6 : len; + PyUnicodeWriter *writer = PyUnicodeWriter_Create(estimate); + if (writer == NULL) { + return NULL; + } + + for (Py_ssize_t i = 0; i < len; i++) { + if (i > 0 && PyUnicodeWriter_WriteUTF8(writer, " | ", 3) < 0) { goto error; } PyObject *p = PyTuple_GET_ITEM(alias->args, i); - if (union_repr_item(&writer, p) < 0) { + if (union_repr_item(writer, p) < 0) { goto error; } } - return _PyUnicodeWriter_Finish(&writer); + return PyUnicodeWriter_Finish(writer); + error: - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); return NULL; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy