前情提要:
前幾天zstd發布了1.4.5版本,加入了--patch-from選項;使用其現有的字典壓縮代碼,實現了差異更新的功能
據稱平均速度是bsdiff的7倍到百倍之間。
正文:
之前偶然發現了bsdiff這個差異更新神器。奈何bsdiff太慢。
對godot引擎進行差異更新,測試patch大小和時間
先看一下2個版本godot的大小:62MB、69MB
➜ Godot ll 總用量 130M -rwxr-xr-x 1 drecol wheel 62M 11月 30 2019 Godot_v3.1.2-stable_x11.64 -rwxr-xr-x 1 drecol wheel 69M 3月 10 20:27 Godot_v3.2.1-stable_x11.64
測試結果:
bsdiff:
➜ Godot /bin/time bsdiff Godot_v3.1.2-stable_x11.64 Godot_v3.2.1-stable_x11.64 bspatch 74.59user 0.35system 1:15.06elapsed 99%CPU (0avgtext+0avgdata 1076036maxresident)k 0inputs+42680outputs (0major+308664minor)pagefaults 0swaps
zstd:
➜ Godot /bin/time zstd --patch-from=Godot_v3.1.2-stable_x11.64 Godot_v3.2.1-stable_x11.64 -o patch
long mode automaticaly triggered
Godot_v3.2.1-stable_x11.64 : 33.78% (71335911 => 24095339 bytes, patch)
0.85user 0.08system 0:00.89elapsed 104%CPU (0avgtext+0avgdata 212788maxresident)k
0inputs+47120outputs (0major+52770minor)pagefaults 0swaps
zstd -7:
➜ Godot /bin/time zstd -7 --patch-from=Godot_v3.1.2-stable_x11.64 Godot_v3.2.1-stable_x11.64 -o patch --zstd=targetLength=4096 --zstd=chainLog=30 long mode automaticaly triggered Godot_v3.2.1-stable_x11.64 : 30.71% (71335911 => 21906223 bytes, patch) 7.29user 0.36system 0:07.65elapsed 100%CPU (0avgtext+0avgdata 1281536maxresident)k 0inputs+42848outputs (0major+319981minor)pagefaults 0swaps
zstd -19:
➜ Godot /bin/time zstd -19 --patch-from=Godot_v3.1.2-stable_x11.64 Godot_v3.2.1-stable_x11.64 -o patch
long mode automaticaly triggered
[Optimal parser notes] Consider the following to improve patch size at the cost of speed:
- Use --single-thread mode in the zstd cli
- Set a larger targetLength (eg. --zstd=targetLength=4096)
- Set a larger chainLog (eg. --zstd=chainLog=30)
Also consdier playing around with searchLog and hashLog
Godot_v3.2.1-stable_x11.64 : 27.51% (71335911 => 19624380 bytes, patch)
31.66user 0.11system 0:31.79elapsed 99%CPU (0avgtext+0avgdata 391192maxresident)k
0inputs+38384outputs (0major+97340minor)pagefaults 0swaps
zstd -19 --zstd=targetLength=4096 --zstd=chainLog=30
➜ Godot /bin/time zstd -19 --patch-from=Godot_v3.1.2-stable_x11.64 Godot_v3.2.1-stable_x11.64 -o patch --zstd=targetLength=4096 --zstd=chainLog=30 long mode automaticaly triggered [Optimal parser notes] Consider the following to improve patch size at the cost of speed: - Use --single-thread mode in the zstd cli - Set a larger targetLength (eg. --zstd=targetLength=4096) - Set a larger chainLog (eg. --zstd=chainLog=30) Also consdier playing around with searchLog and hashLog Godot_v3.2.1-stable_x11.64 : 24.80% (71335911 => 17693645 bytes, patch) 51.60user 0.69system 0:52.33elapsed 99%CPU (0avgtext+0avgdata 2355352maxresident)k 0inputs+34616outputs (0major+588378minor)pagefaults 0swaps
測試結果:
軟件 | 時間 | patch大小 |
bsdiff | ~75秒 | 21MB |
zstd | ~1秒 | 23MB |
zstd -7 --zstd=targetLength=4096 --zstd=chainLog=30 | ~7.5秒 | 21MB |
zstd -19 | ~32秒 | 19MB |
zstd -19 --zstd=targetLength=4096 --zstd=chainLog=30 | ~52秒 | 17MB |
當使用默認壓縮級別時,ztsd幾乎瞬間完成,patch的大小僅比bsdiff大2MB,為23MB
使用-19最高壓縮級別時,zstd花費32秒,所用時間不足bsdiff的一半,同時patch大小比bsdiff小了2MB,為19MB
使用-19 --zstd=targetLength=4096 --zstd=chainLog=30,zstd花費52秒,約為bsdiff所用時間的2/3,patch大小比bsdiff小了4MB,為17MB
bsdiff沒有什么壓縮等級的選項,花費75秒,patch大小21MB
本例中,使用zstd -7 --zstd=targetLength=4096 --zstd=chainLog=30,生成了相同大小的patch,zstd是bsdiff速度的10倍。
結論:
zstd比bsdiff快到不知哪里去了。
patch大小方面,zstd優勢也很明顯。
強烈建議用zstd替代bsdiff
apply patch就不測了。