AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / computer / Perguntas / 1633073
Accepted
Saaru Lindestøkke
Saaru Lindestøkke
Asked: 2021-03-14 09:37:48 +0800 CST2021-03-14 09:37:48 +0800 CST 2021-03-14 09:37:48 +0800 CST

Por que os arquivos tar.xz são 15x menores ao usar a biblioteca tar do Python em comparação com o tar do macOS?

  • 772

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 tarcomando e a tarfilebiblioteca 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:

  • tarno macOS:bsdtar 3.3.2 - libarchive 3.3.2 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.6
  • tarno Raspbian 10:xz (XZ Utils) 5.2.4 liblzma 5.2.4
  • tarfileBiblioteca 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:

Insira a descrição da imagem aquiinsira a descrição da imagem aqui

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?

macos python
  • 3 3 respostas
  • 58224 Views

3 respostas

  • Voted
  1. Best Answer
    Saaru Lindestøkke
    2021-03-14T15:22:54+08:002021-03-14T15:22:54+08:00

    Resposta curta: sim, é seguro usar o Python tarlibpara compactar os dados, nada é perdido em comparação com o BSD tar.

    Problema subjacente: classificação

    Eu acho que o problema subjacente é que o BSD tare o GNU tarsem nenhuma opção de classificação colocam os arquivos no arquivo em uma ordem indefinida.

    O GNU tartem uma --sortopção:

    classifique as entradas do diretório de acordo com ORDER, que é um de none, nameou inode.
    O padrão é --sort=none, que armazena os membros do arquivo na mesma ordem retornada pelo sistema operacional.

    Testando GNUtar

    Para testar isso, instalei o GNU tarno meu Mac com:

    brew install gnu-tar
    

    E depois tareou a mesma pasta, mas com a --sortopção:

    gtar --sort='name' -cJf zsh-archive-sorted.tar.xz /Users/user/Desktop/temp/tar/2021-03-11
    

    O zsh-archive-sorted.tar.xzarquivo tem 1,5 MB, igual ao tamanho do arquivo criado pela biblioteca Python.

    Concatenar em ordem ordenada

    O efeito que a classificação tem no tamanho final do arquivo é ainda demonstrado concatenando primeiro todos os arquivos JSON classificados por nome (que tem a criação unixtime no início) e, em seguida, tarra com BSD tar:

    cat *.json > all.txt
    tar cJf zsh-cat-archive.tar.xz all.txt
    

    O zsh-cat-archive.tar.xzarquivo também tem 1,5 MB.

    tarfileClassificação Python

    Finalmente, a documentação da TarFile.addfunção Python confirma que o Python tarfileclassifica por padrão:

    Os diretórios são adicionados recursivamente por padrão. Isso pode ser evitado configurando recursiva para False. A recursão adiciona entradas em ordem classificada.

    Por que a classificação é importante

    Acho que a razão pela qual a classificação tem tanto impacto no meu caso é a seguinte:

    Meus arquivos JSON contêm localizações de centenas de veículos. A cada minuto eu leio todos os locais, mas apenas alguns desses locais têm um valor diferente de minuto para minuto.
    Ao classificar os arquivos por nome, dois arquivos subsequentes têm caracteres pouco diferentes entre eles. Aparentemente isso é muito favorável para a eficiência de compressão.

    • 307
  2. Giacomo1968
    2021-03-14T09:56:35+08:002021-03-14T09:56:35+08:00

    Tente definir os níveis de compactação na linha de comando do macOS.

    Eu sei que você está perguntando, xzmas explicado nesta resposta aqui , em versões mais antigas do GZip, você pode definir o nível de compactação com uma variável de ambiente como esta:

    GZIP=-9 tar cf zsh-archive.tar.xz folderpath
    

    Dito isto, isso só parece funcionar com o GZip 1.8 e é depreciado em versões posteriores. Portanto, use a opção -I/ --use-compress-program=COMMANDpara tar; observe que esta opção pode não funcionar no macOS, mas colocando aqui de qualquer maneira apenas por precaução. Então o comando mudaria para:

    tar -I 'gzip -9' -cf zsh-archive.tar.xz folderpath
    

    E sim, esses exemplos seriam compactar o arquivo Gzip em vez de xz, mas você pode facilmente alterar o comando para isso para usar xzassim:

    tar -I 'xz -9' -cf zsh-archive.tar.xz folderpath
    

    O xznível de compactação varia de -0a -9com o padrão sendo -6; assim -9é o nível de compressão mais alto.

    Apenas observe que xznão está instalado no macOS por padrão. Para instalá-lo no macOS, você deve primeiro instalar o Homebrew e depois instalar xzvia Homebrew assim:

    brew install xz
    
    • 6
  3. Louis Thompson
    2021-03-15T11:01:04+08:002021-03-15T11:01:04+08:00

    Me faz pensar o que o Python está usando para compactação

    http://tukaani.org/xz/

    Provavelmente está usando as chamadas de função em liblzma. O Tar provavelmente está canalizando o comando xz shell.

    Um comentário rápido sobre --sort=name:

    A opção sort é um aprimoramento relativamente recente do GNU tar e foi introduzido no tar versão 1.28.

    Ele nunca pode ser implementado no BSD tar.

    • 4

relate perguntas

  • Como posso selecionar uma linha no terminal macOS com atalhos de teclado?

  • Sem cores em weechat, tig, htop, ranger, etc

  • Como posso alternar Handoff (Continuidade) no Terminal no macOS?

  • Como forçar o chrome a usar o arquivo pac no macos?

  • “npm config set prefix” falha no diretório de propriedade do usuário no macOS Mojave

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como posso reduzir o consumo do processo `vmmem`?

    • 11 respostas
  • Marko Smith

    Baixar vídeo do Microsoft Stream

    • 4 respostas
  • Marko Smith

    O Google Chrome DevTools falhou ao analisar o SourceMap: chrome-extension

    • 6 respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Martin Hope
    Saaru Lindestøkke Por que os arquivos tar.xz são 15x menores ao usar a biblioteca tar do Python em comparação com o tar do macOS? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh Como posso reduzir o consumo do processo `vmmem`? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Pesquisa do Windows 10 não está carregando, mostrando janela em branco 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 Por que uma conexão de Internet gigabit/s via cabo (coaxial) não oferece velocidades simétricas como fibra? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve