Skip to content

Commit 541cc67

Browse files
committed
Optimize gzip.decompress by omitting list creation
1 parent c56898a commit 541cc67

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

src/isal/isal_zlibmodule.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,17 +1662,37 @@ GzipReader_readall(GzipReader *self, PyObject *Py_UNUSED(ignore))
16621662
{
16631663
/* Try to consume the entire buffer without too much overallocation */
16641664
Py_ssize_t chunk_size = self->buffer_size * 4;
1665-
PyObject *chunk_list = PyList_New(0);
1665+
/* Rather than immediately creating a list, read one chunk first and
1666+
only create a list when more read operations are necessary. */
1667+
PyObject *first_chunk = PyBytes_FromStringAndSize(NULL, chunk_size);
1668+
if (first_chunk == NULL) {
1669+
return NULL;
1670+
}
1671+
ssize_t written_size = GzipReader_read_into_buffer(
1672+
self, (uint8_t *)PyBytes_AS_STRING(first_chunk), chunk_size);
1673+
if (written_size < 0) {
1674+
Py_DECREF(first_chunk);
1675+
return NULL;
1676+
}
1677+
if (written_size < chunk_size) {
1678+
if (_PyBytes_Resize(&first_chunk, written_size) < 0) {
1679+
return NULL;
1680+
}
1681+
return first_chunk;
1682+
}
1683+
1684+
PyObject *chunk_list = PyList_New(1);
16661685
if (chunk_list == NULL) {
16671686
return NULL;
16681687
}
1688+
PyList_SET_ITEM(chunk_list, 0, first_chunk);
16691689
while (1) {
16701690
PyObject *chunk = PyBytes_FromStringAndSize(NULL, chunk_size);
16711691
if (chunk == NULL) {
16721692
Py_DECREF(chunk_list);
16731693
return NULL;
16741694
}
1675-
ssize_t written_size = GzipReader_read_into_buffer(
1695+
written_size = GzipReader_read_into_buffer(
16761696
self, (uint8_t *)PyBytes_AS_STRING(chunk), chunk_size);
16771697
if (written_size < 0) {
16781698
Py_DECREF(chunk);

0 commit comments

Comments
 (0)