diff --git a/news/12803.bugfix.rst b/news/12803.bugfix.rst new file mode 100644 index 00000000000..4193d33e05c --- /dev/null +++ b/news/12803.bugfix.rst @@ -0,0 +1,4 @@ +Improve pip install performance. Files are now extracted in 1MB blocks, +or in one block matching the file size for smaller files. +A decompressor is no longer instantiated when extracting 0 bytes files, +it is not necessary because there is no data to decompress. diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py index a02a193d226..c7d9c09cc65 100644 --- a/src/pip/_internal/operations/install/wheel.py +++ b/src/pip/_internal/operations/install/wheel.py @@ -377,9 +377,13 @@ def save(self) -> None: zipinfo = self._getinfo() - with self._zip_file.open(zipinfo) as f: - with open(self.dest_path, "wb") as dest: - shutil.copyfileobj(f, dest) + # optimization: the file is created by open(), + # skip the decompression when there is 0 bytes to decompress. + with open(self.dest_path, "wb") as dest: + if zipinfo.file_size > 0: + with self._zip_file.open(zipinfo) as f: + blocksize = min(zipinfo.file_size, 1024 * 1024) + shutil.copyfileobj(f, dest, blocksize) if zip_item_is_executable(zipinfo): set_extracted_file_to_default_mode_plus_executable(self.dest_path)