测试bsdiff与bspatch二进制补丁工具


当软件包有新版本发布,如果升级包比较大,每次都要下载完整的包就比较耗时,程序层面还需实现断点续传功能,这个工具挺不错,使用bsdiff工具生成patch,然后把patch传到客户端,客户端使用老版本包和patch文件,用bspatch合并成新包

网站:http://www.daemonology.net/bsdiff/

前一阵测试了一下这个工具,记录一下,也给有需求使用的人做一个参考,以下是主要测试的内容

  1. 内存占用是否符合网站公式说明
  2. 由补丁生成的新版本是否稳定可用

工具使用足够的方便

bsdiff: usage: 
    bsdiff oldfile newfile patchfile
bspatch: usage: 
    bspatch oldfile newfile patchfile

内存占用统计

bsdiff 期望内存占用公式:max(17*n,9*n+m)+O(1),bspatch 期望内存占用:n+m+O(1),其中n为旧版本文件,m为新版本文件

较小软件内存占用

编号 旧版本 新版本 期望内存占用 实际内存占用 O(1) 用时
1 66.03M 68.91M 1.12G 1.12G 1.75M 36.0s
2 68.91M 71.79M 1.17G 1.17G 1.63M 47.0s
3 71.79M 74.67M 1.22G 1.22G -2.49M 52.0s
4 74.67M 77.54M 1.27G 1.27G 276.56K 57.0s
5 77.54M 80.42M 1.32G 1.32G -1.91M 63.0s
6 80.42M 83.3M 1.37G 1.37G -1.11M 69.0s
7 83.3M 86.18M 1.42G 1.41G -1.35M 76.0s

较大软件内存占用

编号 旧版本 新版本 期望内存占用 实际内存占用 O(1) 用时
1 173.58M 204.12M 2.95G 2.95G 3.01M 221.0s
2 204.12M 262.15M 3.47G 3.48G 5.43M 326.0s
3 262.15M 302.75M 4.46G 4.44G -13.89M 452.0s
  • 虚拟机的可用内存有限,再大的文件生成就要出错了

可以得出如下结论

  1. bsdiff内存占用的测试结果与文档中体现的公式相符
  2. O(1)指代的空间占用极小,可视为期望与实际内存之间的系统误差

另外测试了新版本经优化后体积减小的情况,工具可正常工作生成补丁

编号 旧版本 新版本 期望内存占用 实际内存占用 O(1) 用时
1 204.12M 173.58M 3.47G 3.48G 6.28M 159.0s

记录内存占用方法

通过肉眼记录最大内存占用是行不通的,于是有这样一个记录最大内存占用的方法,我用的python实现

首先启动一个线程,它的进入while循环,功能是调用一个包,每隔0.2秒钟获取一下当前的内存信息,如果内存增加,则修改最大占用内存数,否则继续循环,while中会查看一个全局的变量,查看它自己是否应该退出

当线程启动后,使用脚本执行bsdiff命令来创建patch,当创建完成后,设置全局变量为真,子线程获取到全局变量后就可以自行退出了。主函数处应该设置thread.join(),使得主线程等待子线程结束输出最大内存占用等信息

代码在这里: https://gist.github.com/sincerefly/1bd7319f588dc108e1072d6d2b485126

下面是输出:

------------ start(1/3) ------------
('OO1.2.zip', 'OO1.3.zip', 'OO12_upto_OO13')
noraml: 399.63M, max: 3.35G, bsdiff_max_used: 2.95G
expect_max_memory_used: 2.95G, O(1): 3.01M
old size: 173.58M, new size: 204.12M
bsdiff used time: 221.0s
------------ start(2/3) ------------
('OO1.3.zip', 'OO1.4.zip', 'OO13_upto_OO14')
noraml: 395.45M, max: 3.87G, bsdiff_max_used: 3.48G
expect_max_memory_used: 3.47G, O(1): 5.43M
old size: 204.12M, new size: 262.15M
bsdiff used time: 326.0s
------------ start(3/3) ------------
('OO1.4.zip', 'OO1.5.zip', 'OO14_upto_OO15')
noraml: 395.35M, max: 4.84G, bsdiff_max_used: 4.44G
expect_max_memory_used: 4.46G, O(1): -13.89M
old size: 262.15M, new size: 302.75M
bsdiff used time: 452.0s

新文件可用性

之前本来想测试rar,zip,exe,jpg等文件的生成,看一下能不能正常使用

后来无意中发现使用old,new文件通过bsdiff生成的patchfile

然后使用bspatch,把old和patch合成为new2文件,new与new2的文件MD5值是相同的

[root@centos tmptmp]# md5sum kdenlive_new.rar 
2febb62d1f69014e7c197155b6a09f03  kdenlive_new.rar
[root@centos tmptmp]# md5sum kdenlive_new2.rar 
2febb62d1f69014e7c197155b6a09f03  kdenlive_new2.rar

这样来看,可用性还是无需担心

合并patch内存及时间消耗

编号 旧版本 新版本 内存消耗 补丁大小 用时
1 66.03M 68.91M 159.69M 2.75M 2.0s
2 68.91M 71.79M 162.19M 1K 2.0s
3 71.79M 74.67M 160.99M 1K 2.0s
4 173.58M 204.12M 378.61M 29.2M 14.0s
5 204.12M 262.15M 483.04M 55.5M 21.0s
6 262.15M 302.75M 589.44M 61.4M 24.0s
  1. bspatch合并patch功能经测试内存占用与文档中公式相符 n+m+O(1)
  2. 此处列出了补丁大小,1K的情况下是因为1,2,3编号的版本,每次都是在上个版本基础上添加的同一个文件, 1编号首次添加新文件,会大一些,2,3因为在1基础上打包,已经包含这个文件,所以补丁很小

1版本 = 基础版 + 5MB.file 2版本 = 1版本 + 5MB.file 3版本 = 2版本 + 5MB.file

基本就这些了,bsdiff和bspatch工具还是挺不错的