3 pontos por GN⁺ 2025-06-19 | Ainda não há comentários. | Compartilhar no WhatsApp
  • O crate bzip2 0.6.0 adota por padrão libbz2-rs-sys, uma implementação em Rust do algoritmo bzip2, removendo a dependência de C e melhorando ao mesmo tempo o desempenho e a facilidade de cross-compilation
  • O bzip2 é um algoritmo antigo, hoje menos usado, mas vários protocolos e bibliotecas ainda precisam oferecer suporte para cumprir especificações, por isso ele continua presente em partes profundas da árvore de dependências
  • A implementação em Rust usou cerca de 9,66~14,87% menos ciclos de CPU do que a versão em C na compressão, e também melhorou a descompressão em 4,48~10,00% ao longo dos testes
  • Com a remoção de C, os builds para WebAssembly, Windows e Android ficam mais simples, e por padrão libbz2-rs-sys não exporta símbolos, reduzindo também o risco de conflito de símbolos com outras dependências
  • Na auditoria, foram corrigidos 1 bug lógico de off-by-one e algumas limitações do fuzzer, e bibliotecas e aplicações de nível superior que usam bzip2 também passaram a poder ser executadas com MIRI

Mudança da implementação padrão no bzip2 0.6.0

  • O crate bzip2 0.6.0 passa a usar por padrão libbz2-rs-sys, uma implementação em Rust do algoritmo bzip2
  • Ao remover a dependência anterior em C, o crate bzip2 fica mais rápido e mais fácil de cross-compilation
  • O crate libbz2-rs-sys também pode ser compilado como uma biblioteca dinâmica em C, permitindo que projetos em C aproveitem essas melhorias
  • Embora o bzip2 não seja muito usado hoje, muitos protocolos e bibliotecas ainda precisam suportá-lo para cumprir especificações, e ele continua presente em partes profundas da árvore de dependências de vários projetos
  • Os detalhes da implementação podem ser vistos no post anterior Translating bzip2 with c2rust

Resultados de melhoria de desempenho

  • A implementação em Rust geralmente é mais rápida que a implementação em C, e em alguns casos fica em nível semelhante ao desempenho em C
    • Dentro do que se conhece, não há casos realmente mais lentos
  • Nos benchmarks de compressão, houve redução nos ciclos de CPU em relação ao C
    • sample3.ref level 1: 38.51M33.53M, -14.87%
    • silesia-small.tar level 1: 3.43G3.00G, -14.30%
    • silesia-small.tar level 9: 3.47G3.17G, -9.66%
    • O level do bzip2 indica o uso de memória de trabalho e não tem grande impacto no desempenho
    • sample3.ref já aloca mais memória do que o tamanho do arquivo apenas com level 1, então levels mais altos têm pouca relevância
  • O desempenho de descompressão também melhorou em todos os testes
    • sample3.bz2: -4.48%
    • sample1.bz2: -8.63%
    • sample2.bz2: -7.67%
    • dancing-color.ps.bz2: -5.17%
    • re2-exhaustive.txt.bz2: -7.65%
    • zip64support.tar.bz2: -10.00%
  • Na máquina de benchmark com macOS, às vezes os números de desempenho de descompressão aparecem mais baixos
    • A causa não foi identificada, e no macOS era difícil fazer ferramentas de rastreamento de desempenho como o perf funcionarem de forma automatizada

Build e mitigação de conflito de símbolos

  • Em projetos Rust com dependência de C, a cross-compilation muitas vezes funciona de imediato graças ao crate cc, mas quando falha pode ser difícil depurar o erro
    • O link com bibliotecas de sistema também pode gerar problemas confusos e difíceis de reproduzir
    • A compilação de bzip2 para WebAssembly já apresentava problemas havia muito tempo
    • Ao remover a dependência em C e usar apenas código Rust, os builds para WebAssembly, Windows e Android passam a funcionar com mais facilidade
  • libbz2-rs-sys por padrão não exporta símbolos
    • Quando se usa dependência em C, é necessário exportar símbolos para que blocos Rust extern consigam encontrá-los
    • Nomes exportados podem entrar em conflito quando outra dependência declara os mesmos símbolos
    • Se um projeto Rust precisar exportar símbolos, isso pode ser ativado com uma feature flag

Resultados de verificação e auditoria

  • Uma implementação de bzip2 com bom desempenho precisa de algum código unsafe, e reproduzir em Rust a interface em C exige ainda mais código unsafe
    • Esse código pode ser executado no MIRI
    • Bibliotecas ou aplicações de nível mais alto que usam bzip2 agora também podem ser executadas com MIRI
  • Na auditoria, foi encontrado 1 bug lógico de off-by-one e algumas limitações do fuzzer foram corrigidas
  • Este trabalho contou com a ajuda de Alex Crichton, mantenedor do crate bzip2, da Radically Open Security, que forneceu auditoria e expertise, e da NLnet Foundation, que financiou o projeto por meio do e-Commons Fund

Ainda não há comentários.

Ainda não há comentários.