Skip to content

Commit 9b5deeb

Browse files
committed
Add UCS1 fast path
1 parent 120b75c commit 9b5deeb

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

Objects/unicodeobject.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6100,6 +6100,33 @@ _PyUnicode_EncodeUTF32(PyObject *str,
61006100
if (len > PY_SSIZE_T_MAX / 4 - (byteorder == 0))
61016101
return PyErr_NoMemory();
61026102
Py_ssize_t nsize = len + (byteorder == 0);
6103+
6104+
#if PY_LITTLE_ENDIAN
6105+
int native_ordering = byteorder <= 0;
6106+
#else
6107+
int native_ordering = byteorder >= 0;
6108+
#endif
6109+
if (kind == PyUnicode_1BYTE_KIND) {
6110+
// gh-139156: Don't use PyBytesWriter API here since it has an overhead
6111+
// on short strings
6112+
PyObject *v = PyBytes_FromStringAndSize(NULL, nsize * 4);
6113+
if (v == NULL) {
6114+
return NULL;
6115+
}
6116+
6117+
/* output buffer is 4-bytes aligned */
6118+
assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 4));
6119+
uint32_t *out = (uint32_t *)PyBytes_AS_STRING(v);
6120+
if (byteorder == 0) {
6121+
*out++ = 0xFEFF;
6122+
}
6123+
if (len > 0) {
6124+
ucs1lib_utf32_encode((const Py_UCS1 *)data, len,
6125+
&out, native_ordering);
6126+
}
6127+
return v;
6128+
}
6129+
61036130
PyBytesWriter *writer = PyBytesWriter_Create(nsize * 4);
61046131
if (writer == NULL) {
61056132
return NULL;
@@ -6123,16 +6150,6 @@ _PyUnicode_EncodeUTF32(PyObject *str,
61236150
else
61246151
encoding = "utf-32";
61256152

6126-
#if PY_LITTLE_ENDIAN
6127-
int native_ordering = byteorder <= 0;
6128-
#else
6129-
int native_ordering = byteorder >= 0;
6130-
#endif
6131-
if (kind == PyUnicode_1BYTE_KIND) {
6132-
ucs1lib_utf32_encode((const Py_UCS1 *)data, len, &out, native_ordering);
6133-
return PyBytesWriter_Finish(writer);
6134-
}
6135-
61366153
PyObject *errorHandler = NULL;
61376154
PyObject *exc = NULL;
61386155
PyObject *rep = NULL;

0 commit comments

Comments
 (0)