henry_flower: A melancholy wolf (Default)
henry_flower ([personal profile] henry_flower) wrote2024-01-27 08:11 pm

Низька компресія, висока компресія

На жаль, це не про двигуни. Тобто про двигуни, але не ті.

Вікіпідійна сторінка аркхайвних форматів ув таблиці Compression only має назви яких я не чув: rzip (шо?), snappy (га?) і деякі інші, про які чув, але користувався ніколи.

Може я missing out?? Протестувавши їх 9 штук можу повторити банальне спостереження про пробіг, що може відрізнятися.

Наприклад, для 15MB éкзек'ютаблу:

$ ./comprtest /usr/libexec/gdb | tee small.txt
szip             0.07  44.73          8617411
gzip             0.60  61.17          6054706
compress         0.16  44.36          8675673
bzip2            0.97  63.54          5684994
rzip             1.15  64.00          5613217
lzip             5.71  70.52          4596226
lzop             0.03  47.27          8220932
xz               5.45  70.58          4586452
zstd             0.06  61.42          6015779

де стовпчик

  • 2--час ув секундах;
  • 3 це 100(1-compressedorig) , тобто чим вищий %, тим є ліпший результата;
  • 4--фінальний розмір.

або барчартом:

$ sort -nk3 small.txt | cpp -P plot.gp | gnuplot -persist

comprtest--пролетарський шелóвський скрипта, який ув лупі годує або всі 9ти аркхайвери, або лише ті, які користувач вказав:

$ ./comprtest /etc/services xz bzip2
xz               0.18  84.65           107724
bzip2            0.03  81.24           131627

Нічого екстра-цікавого він не містить, окрім хфункції cc(), від якої у мене палає:

#!/bin/sh
# shellcheck disable=2016,2086,2068
set -e

archivers='szip gzip compress bzip2 rzip lzip lzop xz zstd'
input=${1:?Usage: comprtest file}; shift
isize=`wc -c < "$input"`

cc() { for c; do command -v $c>/dev/null || { echo no $c 1>&2;return 1;}; done;}
cc time ${@:-$archivers}
tmp=`mktemp -u tmp.XXXXXX`
trap 'rm -f $tmp' 0 1 2 15

for c in ${@:-$archivers}; do
    echo $c
    case $c in
        szip ) args='< "$input" > $tmp' ;;
        rzip ) args='-k -o $tmp "$input"' ;;
        *    ) args='-c "$input" > $tmp'
    esac

    eval "time -p $c $args" 2>&1 | awk '/real/ {print $2}'
    osize=`wc -c < $tmp`

    echo $isize $osize | awk '{print 100*(1-$2/($1==0?$2:$1))}'
    echo $osize
    rm $tmp
done | xargs -n4 printf "%-8s  %11.2f  %6.2f  %15d\n"

Чому ув всіх борн-лайк шелах, окрім башу, команда type друкує помилки на stdout? Замість мінімального

type a b c >/dev/null

який поверне 0, якщо всі з a, b, c є присутні (або відріпортує на stderr якщо хтось не знайшовся і поверне >= 1), треба писати ось цей маразм:

cc() { for c; do command -v $c>/dev/null || { echo no $c 1>&2;return 1;}; done;}

Підозрюю все почалосі з ash, з якого виросли більшість опенсоурсних шелів. Навіть busybox скопіював то майже verbatim, я спеціяльно подивився.

До речі, якщо хтось знає як написати cc() коротше за 80 символів, буду вдячний.

Добро. (Не буде.) Барчарта генерується простим пенсільванісійським ґнуплотом, дейта якому віддає cpp (ґнуплот не бажає зберігати stdin собі до буфера і на графіку з 2ма абсцисами з stdin отримує інфаркта дупи).

$ cat plot.gp
$data <<E
#include "/dev/stdin"
E
set key tmargin
set xtics rotate by -30 left
set y2tics
set ylabel "Seconds"
set y2label "%"
set style data histograms
set style fill solid
plot $data using 2 axis x1y1 title "Time", \
     "" using 3:xticlabels(1) axis x1y2 title "Space saving"

На xml-файлах запхнутих до .tar розміром 314MB, xz програє rzip'у по всім параметрам, а швидкість lzop'у вражає:

$ ./comprtest ~/Downloads/emacs.stackexchange.tar
szip             1.78  63.70        119429565
gzip             7.19  77.59         73724710
compress         4.06  67.17        108015563
bzip2           21.27  83.36         54751478
rzip            17.51  85.93         46304199
lzip           120.57  85.06         49151518
lzop             0.69  63.63        119667058
xz             125.91  85.55         47559464
zstd             1.35  79.40         67766890

Ув якості домашнього завдання, можете додати перевірку до comprtest чи є foo та bar

$ ./comprtest file foo bar

ув змінній archivers.


Post a comment in response:

If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting