gh-158585: Optimize PyBytesWriter_FinishWithSize() - #158586
Conversation
Add specialized bytes_resize_inplace() and inline PyBytesWriter_Discard() in PyBytesWriter_FinishWithSize(). Add also bytes_get_char() function.
c73d897 to
9571cba
Compare
|
I ran a quick benchmark on Fedora 44 with
Benchmark hidden because not significant (1): byteswriter_a Benchmark: import _testcapi, pyperf
runner = pyperf.Runner()
# use small buffer
runner.bench_func('byteswriter_a', _testcapi.byteswriter_a)
runner.bench_func('byteswriter_abc', _testcapi.byteswriter_abc)
runner.bench_func('byteswriter_highlevel', _testcapi.byteswriter_highlevel)
# use bytes object
runner.bench_func('byteswriter_repeat', _testcapi.byteswriter_repeat)
runner.bench_func('byteswriter_truncate', _testcapi.byteswriter_truncate)Patch to add C benchmarks: Detailsdiff --git a/Modules/_testcapi/bytes.c b/Modules/_testcapi/bytes.c
index f5a5fb0481d..6a48a778fac 100644
--- a/Modules/_testcapi/bytes.c
+++ b/Modules/_testcapi/bytes.c
@@ -380,6 +380,21 @@ static PyType_Spec Writer_spec = {
};
+static PyObject *
+byteswriter_a(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
+{
+ PyBytesWriter *writer = PyBytesWriter_Create(1);
+ if (writer == NULL) {
+ return NULL;
+ }
+
+ char *str = PyBytesWriter_GetData(writer);
+ memcpy(str, "a", 1);
+
+ return PyBytesWriter_Finish(writer);
+}
+
+
static PyObject *
byteswriter_abc(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
@@ -395,6 +410,36 @@ byteswriter_abc(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
}
+static PyObject *
+byteswriter_repeat(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
+{
+ PyBytesWriter *writer = PyBytesWriter_Create(300);
+ if (writer == NULL) {
+ return NULL;
+ }
+
+ char *str = PyBytesWriter_GetData(writer);
+ memset(str, 'x', 300);
+
+ return PyBytesWriter_Finish(writer);
+}
+
+
+static PyObject *
+byteswriter_truncate(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
+{
+ PyBytesWriter *writer = PyBytesWriter_Create(300);
+ if (writer == NULL) {
+ return NULL;
+ }
+
+ char *str = PyBytesWriter_GetData(writer);
+ memset(str, 'x', 300);
+
+ return PyBytesWriter_FinishWithSize(writer, 200);
+}
+
+
static PyObject *
byteswriter_resize(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
{
@@ -606,7 +651,10 @@ corrupt_bytes(PyObject *Py_UNUSED(module), PyObject *args)
static PyMethodDef test_methods[] = {
{"bytes_resize", bytes_resize, METH_VARARGS},
{"bytes_join", bytes_join, METH_VARARGS},
+ {"byteswriter_a", byteswriter_a, METH_NOARGS},
{"byteswriter_abc", byteswriter_abc, METH_NOARGS},
+ {"byteswriter_repeat", byteswriter_repeat, METH_NOARGS},
+ {"byteswriter_truncate", byteswriter_truncate, METH_NOARGS},
{"byteswriter_resize", byteswriter_resize, METH_NOARGS},
{"byteswriter_highlevel", byteswriter_highlevel, METH_NOARGS},
{"test_byteswriter_ptr", test_byteswriter_ptr, METH_NOARGS}, |
|
|
Add specialized bytes_resize_inplace() and inline
PyBytesWriter_Discard() in PyBytesWriter_FinishWithSize().
Add also bytes_get_char() function.
PyBytesWriterimplementation #158585