Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 20 additions & 22 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,49 +522,47 @@ list_dealloc(PyObject *self)
static PyObject *
list_repr_impl(PyListObject *v)
{
PyObject *s;
_PyUnicodeWriter writer;
Py_ssize_t i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
return i > 0 ? PyUnicode_FromString("[...]") : NULL;
int res = Py_ReprEnter((PyObject*)v);
if (res != 0) {
return (res > 0 ? PyUnicode_FromString("[...]") : NULL);
}

_PyUnicodeWriter_Init(&writer);
writer.overallocate = 1;
/* "[" + "1" + ", 2" * (len - 1) + "]" */
writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1;
Py_ssize_t prealloc = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1;
PyUnicodeWriter *writer = PyUnicodeWriter_Create(prealloc);
if (writer == NULL) {
goto error;
}

if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0)
if (PyUnicodeWriter_WriteChar(writer, '[') < 0) {
goto error;
}

/* Do repr() on each element. Note that this may mutate the list,
so must refetch the list size on each iteration. */
for (i = 0; i < Py_SIZE(v); ++i) {
for (Py_ssize_t i = 0; i < Py_SIZE(v); ++i) {
if (i > 0) {
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
if (PyUnicodeWriter_WriteUTF8(writer, ", ", 2) < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is faster, PyUnicodeWriter_WriteUTF8(writer, ", ", 2) or two PyUnicodeWriter_WriteChar()?

This is an idle question. Even if the latter is marginally faster, it may still be more preferable to use the former. But if the difference is significant, this may be a question for optimization.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is faster, PyUnicodeWriter_WriteUTF8(writer, ", ", 2) or two PyUnicodeWriter_WriteChar()?

Two PyUnicodeWriter_WriteChar() calls is faster:

+----------------+-------------+-----------------------+
| Benchmark      | change_utf8 | change_2char          |
+================+=============+=======================+
| repr([])       | 50.2 ns     | 54.0 ns: 1.07x slower |
+----------------+-------------+-----------------------+
| repr(list3)    | 825 ns      | 802 ns: 1.03x faster  |
+----------------+-------------+-----------------------+
| repr(list4)    | 2.89 us     | 2.66 us: 1.09x faster |
+----------------+-------------+-----------------------+
| Geometric mean | (ref)       | 1.01x faster          |
+----------------+-------------+-----------------------+

goto error;
}
}

s = PyObject_Repr(v->ob_item[i]);
if (s == NULL)
goto error;

if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) {
Py_DECREF(s);
if (PyUnicodeWriter_WriteRepr(writer, v->ob_item[i]) < 0) {
goto error;
}
Py_DECREF(s);
}

writer.overallocate = 0;
if (_PyUnicodeWriter_WriteChar(&writer, ']') < 0)
if (PyUnicodeWriter_WriteChar(writer, ']') < 0) {
goto error;
}

Py_ReprLeave((PyObject *)v);
return _PyUnicodeWriter_Finish(&writer);
return PyUnicodeWriter_Finish(writer);

error:
_PyUnicodeWriter_Dealloc(&writer);
if (writer != NULL) {
PyUnicodeWriter_Discard(writer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not PyUnicodeWriter_Discard(NULL) be no-op?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I modified PyUnicodeWriter_Discard(writer) to do nothing if writer is NULL.

}
Py_ReprLeave((PyObject *)v);
return NULL;
}
Expand Down
Loading