]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117151: optimize BufferedWriter(), do not buffer writes that are the buffer size...
authormorotti <r.morotti@gmail.com>
Tue, 23 Apr 2024 15:51:20 +0000 (16:51 +0100)
committerGitHub <noreply@github.com>
Tue, 23 Apr 2024 15:51:20 +0000 (18:51 +0300)
BufferedWriter() was buffering calls that are the exact same size as the buffer. it's a very common case to read/write in blocks of the exact buffer size.

it's pointless to copy a full buffer, it's costing extra memory copy and the full buffer will have to be written in the next call anyway.

Co-authored-by: rmorotti <romain.morotti@man.com>
Modules/_io/bufferedio.c

index 4133d3438253dd586447c7974a9e6a23ca09495c..aa52711941d374a7a68d2683a8cc6e0a14e3002e 100644 (file)
@@ -2092,7 +2092,7 @@ _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
         self->raw_pos = 0;
     }
     avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
-    if (buffer->len <= avail) {
+    if (buffer->len <= avail && buffer->len < self->buffer_size) {
         memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
         if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
             self->write_pos = self->pos;
@@ -2161,7 +2161,7 @@ _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
     /* Then write buf itself. At this point the buffer has been emptied. */
     remaining = buffer->len;
     written = 0;
-    while (remaining > self->buffer_size) {
+    while (remaining >= self->buffer_size) {
         Py_ssize_t n = _bufferedwriter_raw_write(
             self, (char *) buffer->buf + written, buffer->len - written);
         if (n == -1) {