]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-129813, PEP 782: Use PyBytesWriter in _io.FileIO.readall (#138901)
authorCody Maloney <cmaloney@users.noreply.github.com>
Mon, 15 Sep 2025 20:38:01 +0000 (13:38 -0700)
committerGitHub <noreply@github.com>
Mon, 15 Sep 2025 20:38:01 +0000 (22:38 +0200)
Performance about the same, using the benchmark from gh-120754:

```
pyperf compare_to main.json pep782.json
read_file_small: Mean +- std dev: [main] 5.71 us +- 0.05 us -> [pep782] 5.68 us +- 0.05 us: 1.01x faster
read_file_large: Mean +- std dev: [main] 89.7 us +- 0.9 us -> [pep782] 86.9 us +- 0.8 us: 1.03x faster
read_all_rst_bytes: Mean +- std dev: [main] 926 us +- 8 us -> [pep782] 920 us +- 12 us: 1.01x faster
read_all_rst_text: Mean +- std dev: [main] 2.24 ms +- 0.02 ms -> [pep782] 2.17 ms +- 0.04 ms: 1.03x faster

Benchmark hidden because not significant (1): read_all_py_bytes

Geometric mean: 1.01x faster
```

Modules/_io/fileio.c

index c0b6c6425184af01f887b7c8ed537d52a21565c9..ed731da32beb43aab79d009f62b3f74e02b15f37 100644 (file)
@@ -739,7 +739,7 @@ _io_FileIO_readall_impl(fileio *self)
 /*[clinic end generated code: output=faa0292b213b4022 input=10d8b2ec403302dc]*/
 {
     Py_off_t pos, end;
-    PyObject *result;
+    PyBytesWriter *writer;
     Py_ssize_t bytes_read = 0;
     Py_ssize_t n;
     size_t bufsize;
@@ -794,10 +794,10 @@ _io_FileIO_readall_impl(fileio *self)
         }
     }
 
-
-    result = PyBytes_FromStringAndSize(NULL, bufsize);
-    if (result == NULL)
+    writer = PyBytesWriter_Create(bufsize);
+    if (writer == NULL) {
         return NULL;
+    }
 
     while (1) {
         if (bytes_read >= (Py_ssize_t)bufsize) {
@@ -806,18 +806,18 @@ _io_FileIO_readall_impl(fileio *self)
                 PyErr_SetString(PyExc_OverflowError,
                                 "unbounded read returned more bytes "
                                 "than a Python bytes object can hold");
-                Py_DECREF(result);
+                PyBytesWriter_Discard(writer);
                 return NULL;
             }
 
-            if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
-                if (_PyBytes_Resize(&result, bufsize) < 0)
+            if (PyBytesWriter_GetSize(writer) < (Py_ssize_t)bufsize) {
+                if (PyBytesWriter_Resize(writer, bufsize) < 0)
                     return NULL;
             }
         }
 
         n = _Py_read(self->fd,
-                     PyBytes_AS_STRING(result) + bytes_read,
+                     (char*)PyBytesWriter_GetData(writer) + bytes_read,
                      bufsize - bytes_read);
 
         if (n == 0)
@@ -827,20 +827,16 @@ _io_FileIO_readall_impl(fileio *self)
                 PyErr_Clear();
                 if (bytes_read > 0)
                     break;
-                Py_DECREF(result);
+                PyBytesWriter_Discard(writer);
                 Py_RETURN_NONE;
             }
-            Py_DECREF(result);
+            PyBytesWriter_Discard(writer);
             return NULL;
         }
         bytes_read += n;
     }
 
-    if (PyBytes_GET_SIZE(result) > bytes_read) {
-        if (_PyBytes_Resize(&result, bytes_read) < 0)
-            return NULL;
-    }
-    return result;
+    return PyBytesWriter_FinishWithSize(writer, bytes_read);
 }
 
 /*[clinic input]