Contexto
Estou compactando pastas de ~ 1,3 GB, cada uma preenchida com 1440 arquivos JSON e descobri que há uma diferença de 15 vezes entre usar o tar
comando e a tarfile
biblioteca interna do Python no macOS ou Raspbian 10 (Buster)
Exemplo de trabalho mínimo
Este script compara os dois métodos:
#!/usr/bin/env python3
from pathlib import Path
from subprocess import call
import tarfile
fullpath = Path("/Users/user/Desktop/temp/tar/2021-03-11")
zsh_out = Path(fullpath.parent, "zsh-archive.tar.xz")
py_out = Path(fullpath.parent, "py-archive.tar.xz")
# tar using terminal
# tar cJf zsh-archive.tar.xz folderpath
call(["tar", "cJf", zsh_out, fullpath])
# tar using tarfile library
with tarfile.open(py_out, "w:xz") as tar:
tar.add(fullpath, arcname=fullpath.stem)
# Print filesizes
print(f"zsh tar filesize: {round(Path(zsh_out).stat().st_size/(1024*1024), 2)} MB")
print(f"py tar filesize: {round(Path(py_out).stat().st_size/(1024*1024), 2)} MB")
A saída é:
zsh tar filesize: 23.7 MB
py tar filesize: 1.49 MB
As versões que uso são as seguintes:
tar
no macOS:bsdtar 3.3.2 - libarchive 3.3.2 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.6
tar
no Raspbian 10:xz (XZ Utils) 5.2.4 liblzma 5.2.4
tarfile
Biblioteca Python:0.9.0
Coisas que eu tentei
Após a compactação, extraí os dois arquivos e comparei a pasta resultante com:
diff -r py-archive-expanded zsh-archive-expanded
Não houve diferença.
Se eu comparar os dois arquivos tar diretamente, eles parecem diferentes:
➜ diff zsh-archive.tar.xz py-archive.tar.xz
Binary files zsh-archive.tar.xz and py-archive.tar.xz differ
Se eu inspecionar os arquivos com Quicklook (e o plugin Betterzip), vejo que os arquivos no arquivo estão ordenados de maneira diferente:
A esquerda é zsh-archive.tar.xz
, a direita é py-archive.tar.xz
:
O arquivo zsh usa uma ordem desconhecida e o arquivo Python ordena o arquivo por data de modificação. Não tenho certeza se isso importa.
Pergunta
O que está acontecendo? Estou perdendo algo usando a biblioteca Python para compactar meus dados? A diferença de 15 vezes no tamanho é um indicador de algum problema? Ou posso prosseguir com segurança e usar a implementação eficiente do Python?