高性能diff&patch算法 -- 如何將微信Apk的官方增量包20.4M縮小到7.0M

技術分享PPT: 高性能diff&patch算法

-- 如何將微信Apk的官方增量包20.4M縮小到7.0M   
    作者: [email protected]   2018.03.16

什麼是diff&patch算法

  • 原理抽象概述: … …

3種有效的diff算法

  • 增量壓縮流
  • 同步流
  • 覆蓋線流

其他:按行、按文件等…


增量壓縮diff算法

  • 最容易實現的可以自己diy出來的一種有效算法
  • 尋找一種高效的基礎壓縮算法
  • 實現技巧:
    • 拼接old+new一起壓縮,輸出new部分壓縮得到的編碼爲補丁;patch時先壓縮old並和補丁拼一起解壓縮,丟棄前面old大小的數據,後面的就是新生成的new
  • 優缺點:
    • 容易實現,算法選擇的好時效果很贊;適應範圍較窄(數據較大時補丁可能突然異常變大),因爲要壓縮速度可能慢等

覆蓋線diff算法

  • BsDiff
  • HDiffPatch
  • 實現原理:
    • 二維矩陣概念
    • 覆蓋線概念
    • 後綴數組(QuickSort\libdivsufsort)
  • 優缺點:
    • 補丁小、diff內存佔用大、運行慢、patch快
    • patch內存佔用O(m+n)複雜度的誤解: 這只是BsDiff的具體實現問題;HDiffPatch就可以做到實際內存佔用O(1)的patch過程;(HDiffPatch也提供了降低diff時間和空間複雜度的實現版本:同步diff算法的實現)
  • 小胡瓜Courgette:
    • 原理:針對程序,反編譯old和new、diff源代碼、反編譯old並patch源代碼、編譯成new

同步diff算法

  • 原理:分塊hash和roll hash的對比
  • 一些實現:同步工具、xdelta?HDiffPatch
  • 優缺點:
    • 可以支持動態CS模式(甚至允許C損壞)、速度快、可以支持超大文件;(xdelta對超大文件支持不好)

Apk的diff算法選擇

  • zip、jar、apk的關係 (另外: ipa)
  • Jar包簽名(Apk v1 Sign)
  • BsDiffHDiffPatch
    • 爲什麼微信Apk663版到665版的升級包是20.4M
    • 遇到的適應問題:壓縮算法破壞了“現場”
  • 直觀的解決思路:zip包的針對性優化
    • 將zip抽象成未壓縮狀態的數據交給diff算法,patch時輸出標準zip包

如何支持嚴苛的Apk V2版簽名

  • Apk v2 Sign介紹
    • 額外:渠道包失效? 現在該如何在包中“夾帶私貨”
  • 增量更新解決思路:
    • newZip=AndroidSDK#apksigner(ApkNormalized(newZip)) before ZipDiff
    • patch重建newZip時byte by byte的相等保證;
    • 風險提示、安全保證手段
  • ApkDiffPatch方案:
    • Zip(Jar,Apk) file by file Diff & Patch, create minimal differential, support apk v2 sign & Jar sign(apk v1).

有了BsDiff或HDiffPatch爲什麼還需要ApkDiffPatch?

ApkDiffPatch: v1.0
BsDiff: v4.3
HDiffPatch: v2.2.6   
Google Play patches: https://github.com/andrewhayden/archive-patcher  v1.0 
                 (test by https://github.com/googlesamples/apk-patch-size-estimator )
======================================================================================
                                        BsDiff HDiffPatch archive-patcher ApkDiffPatch
  oldVersion -> newVersion     newSize  (bzip2)  (zlib)      (gzip)    (zlib)  (lzma)
--------------------------------------------------------------------------------------
 v63->chrome-64-0-3282-123.apk 43879588 32916357 32621974  18776996  15995242 13896562
      chrome-64-0-3282-137.apk 43879588 28895294 28538751   1357320   1341073  1149331
      chrome-65-0-3325-109.apk 43592997 31771385 31540550  16427116  14415021 12356765
 v70->google-maps-9-71-0.apk   50568872 37992141 37531799  17293163  14562607 11430622
      google-maps-9-72-0.apk   54342938 41897706 41475595  21301751  18752320 14066134
v660->weixin661android1220.apk 61301316 17565557 17372003   1927833   1794219  1659286
      weixin662android1240.apk 63595334 38349926 38025483  22100454  18392769 15556315
      weixin663android1260.apk 63595326 11614415 11531258   1044656    937920   940060
      weixin665android1280.apk 63669882 21423459 21176790   9621032   9003472  7392063
--------------------------------------------------------------------------------------
Average Compression              100.0%    56.3%    55.8%     23.5%     20.4%    16.8%
======================================================================================

額外:下載服務商的可能優化策略討論

  • 無法重新打包和簽名的情況下如何支持v2簽名Apk包的類似優化增量包?

    • 收集常見的兼容壓縮算法庫;
    • 動態計算出apk使用的可能壓縮庫和其壓縮參數,以保證patch時byteByByte還原; 這樣能解決絕大部分Apk的升級;否則剩下的Apk就退回類似直接diff的方案;
  • Google Play patches : archive-patcher方案:

    • file by file Diff & Patch; is an open-source project that allows space-efficient patching of zip archives. Many common distribution formats (such as jar and apk) are valid zip archives; archive-patcher works with all of them.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章