当软件包有新版本发布,如果升级包比较大,每次都要下载完整的包就比较耗时,程序层面还需实现断点续传功能,这个工具挺不错,使用bsdiff工具生成patch,然后把patch传到客户端,客户端使用老版本包和patch文件,用bspatch合并成新包
网站:http://www.daemonology.net/bsdiff/
前一阵测试了一下这个工具,记录一下,也给有需求使用的人做一个参考,以下是主要测试的内容
- 内存占用是否符合网站公式说明
- 由补丁生成的新版本是否稳定可用
工具使用足够的方便
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 |
- 虚拟机的可用内存有限,再大的文件生成就要出错了
可以得出如下结论
- bsdiff内存占用的测试结果与文档中体现的公式相符
- 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 |
- bspatch合并patch功能经测试内存占用与文档中公式相符 n+m+O(1)
- 此处列出了补丁大小,1K的情况下是因为1,2,3编号的版本,每次都是在上个版本基础上添加的同一个文件, 1编号首次添加新文件,会大一些,2,3因为在1基础上打包,已经包含这个文件,所以补丁很小
1版本 = 基础版 + 5MB.file 2版本 = 1版本 + 5MB.file 3版本 = 2版本 + 5MB.file
基本就这些了,bsdiff和bspatch工具还是挺不错的