zstd差异更新对比bsdiff
前情提要:
前几天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就不测了。