データの節約: アプリのアップデートのサイズを 65% 削減
2016年12月16日金曜日
[この記事は Andrew Hayden、Google Play ソフトウェア エンジニアによる Android Developers Blog の記事 "Saving Data: Reducing the size of App Updates by 65%" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。]
Android ユーザーは、Google Play で数百億のアプリやゲームをダウンロードしています。また、デベロッパーは頻繁にアプリをアップデートして、ユーザーにすばらしいコンテンツを提供したり、セキュリティを改善したり、ユーザー エクスペリエンス全般を向上させたりしています。こういったアップデートでは、多くのデータをダウンロードする必要があります。しかしユーザーは、端末で消費したデータ量を気にしています。Google は今年、bsdiff アルゴリズム(Colin Percival 氏が開発)の利用開始を発表しました。bsdiff の利用によって、アプリの完全な APK のサイズと比べると、アップデートのサイズを平均 47% 減らすことができました。
本日(*原文公開当時)は、さらにアップデートのサイズを削減する新たなアプローチをお知らせします。それは、ファイルごとのパッチ適用です。ファイルごとのパッチ適用によるアプリのアップデートでは、完全なアプリよりも平均 65% 小さくなり、場合によっては 90% 以上小さくなることもあります。
以前のアプローチと比較すると、なんと 1 日あたり最大 6 ペタバイトのユーザーデータを節約できることになります。
この方法では、アプリの新しいバージョンを入手する際に、Google Play から端末にアプリの旧版と新版との 差分 を記述したパッチが送信されます。
たとえば、まもなく出版される本の著者が 1 文だけ変更したいとします。全文を送り直すよりも、編集者にその変更内容を伝える方がはるかに簡単です。同じように、パッチを使うと APK 全体をダウンロードするよりもはるかにサイズが小さくなり、ダウンロード時間も短縮されます。
ファイルごとのパッチ適用で使われるテクニック
Android アプリは APK としてパッケージ化されています。APK は、特殊なルールに基づいた ZIP ファイルです。ZIP ファイル(と APK)の中にあるほとんどのコンテンツは、Deflate と呼ばれるテクノロジーを使って圧縮されています。Deflate はデータの圧縮には優れていますが、元の(圧縮されていない)コンテンツの変更点を特定するのが非常に難しくなるという欠点もあります。元のコンテンツをわずかに変更しただけでも(本の中の 1 語だけ変更するように)、Deflate が出力する圧縮データは まったく異なるものに見える場合があります。 元の コンテンツの差分を作るのは簡単でも、 圧縮された コンテンツの差分を作るのはとても難しいため、パッチは非効率になってしまいます。
左側の圧縮されていないテキストを 1 文字変更しただけで、右側の圧縮されたテキストがどのくらい変わるかをご覧ください。
そのため、ファイルごとのパッチは、圧縮されていないデータで検出された差分に基づきます。パッチの生成にあたって、まず古いファイルと新しいファイルの両方を解凍し、差分を計算します(ここでは、まだ bsdiff を利用しています)。次に、パッチを適用するため、古いファイルを解凍して圧縮されていないコンテンツに差分を適用し、新しいファイルを再圧縮します。その際に、端末上の APK が Play Store 上の APK とバイト単位で完全に一致していることを確認する必要があります(この理由については、APK 署名スキーマ v2 をご覧ください)。
新しいファイルの再圧縮には、2 つの問題があります。1 つ目の問題は、Deflate の設定によって Deflate の出力が色々と変わることです。そもそも、圧縮の際にどのような設定が使われたのかはわかりません。2 つ目は、Deflate には多くのバージョンが存在しており、ユーザーの端末上にある Deflate が適切なバージョンか確認する必要があります。
幸運にも、Play Store のアプリを分析したところ、Play Store のほぼすべての Deflate コンテンツで、zlib(もっとも普及している Deflate ライブラリ)に基づいた、互換性がある最近のバージョンの Deflate が使われていることがわかりました。さらに、実質的に使われている設定は、デフォルト(level=6)と最大(level=9)の圧縮設定だけでした。
以上のことを踏まえると、元々の Deflate 設定を検出して再現できると言えます。つまり、データを解凍し、パッチを適用してデータを再圧縮し、元々アップロードされたものと まったく同じバイト列 を作ることができます。
ただしこの方式には、端末側で必要な処理能力が高くなるという欠点もあります。最近(たとえば、2015 年以降)の端末では、再圧縮には 1 メガバイトあたり 1 秒少しかかり、古い端末や能力が低い端末はさらに時間がかかります。現時点の分析によると、平均で、パッチのサイズが半分になるとパッチの適用(再圧縮を含めたファイルごとのパッチ適用)にかかる時間は倍になります。
今のところ、この新しいパッチ テクノロジーの利用は自動アップデートのみに制限しています。これは通常、夜間にスマートフォンが電源に接続され、ユーザーが使用していない可能性が高いときにバックグラウンドで行われるアップデートです。これによって、ユーザーが手動でアプリをアップデートする際に、いつもより長く待たなければならないという事態を回避しています。
ファイルごとのパッチ適用の効率性
以下に、すでにファイルごとのパッチ適用を使っているアプリのアップデートの例を示します。
免責事項: 現在、ファイルごとのパッチはバックグラウンドでのみ利用されており、インタラクティブなアップデートには利用されていないため、手動で「アップデート」を押した際に表示されるパッチサイズとは異なる場合があります。
データを節約してユーザー(そしてデベロッパー)をハッピーに
以上の変更は、10 億人以上の Android ユーザー コミュニティが、最小限のデータ量でアプリの定期アップデートを行えるように設計されています。一番の長所は、デベロッパーは何もする必要がないことです。このアップデートのサイズ削減は、無償で行われます。
技術的な詳細など、ファイルごとのパッチ適用についてさらに詳しく知りたい方は、Archive Patcher GitHub プロジェクトをご覧ください。ソースコードを含む情報を閲覧できます。ファイルごとのパッチ適用は、完全なオープンソースです。
APK サイズをさらに削減したいデベロッパーの方は、APK サイズ削減のための一般的な推奨事項もご覧ください。
Posted by Khanh LeViet - Developer Relations Team
Android ユーザーは、Google Play で数百億のアプリやゲームをダウンロードしています。また、デベロッパーは頻繁にアプリをアップデートして、ユーザーにすばらしいコンテンツを提供したり、セキュリティを改善したり、ユーザー エクスペリエンス全般を向上させたりしています。こういったアップデートでは、多くのデータをダウンロードする必要があります。しかしユーザーは、端末で消費したデータ量を気にしています。Google は今年、bsdiff アルゴリズム(Colin Percival 氏が開発)の利用開始を発表しました。bsdiff の利用によって、アプリの完全な APK のサイズと比べると、アップデートのサイズを平均 47% 減らすことができました。
本日(*原文公開当時)は、さらにアップデートのサイズを削減する新たなアプローチをお知らせします。それは、ファイルごとのパッチ適用です。ファイルごとのパッチ適用によるアプリのアップデートでは、完全なアプリよりも平均 65% 小さくなり、場合によっては 90% 以上小さくなることもあります。
以前のアプローチと比較すると、なんと 1 日あたり最大 6 ペタバイトのユーザーデータを節約できることになります。
この方法では、アプリの新しいバージョンを入手する際に、Google Play から端末にアプリの旧版と新版との 差分 を記述したパッチが送信されます。
たとえば、まもなく出版される本の著者が 1 文だけ変更したいとします。全文を送り直すよりも、編集者にその変更内容を伝える方がはるかに簡単です。同じように、パッチを使うと APK 全体をダウンロードするよりもはるかにサイズが小さくなり、ダウンロード時間も短縮されます。
ファイルごとのパッチ適用で使われるテクニック
Android アプリは APK としてパッケージ化されています。APK は、特殊なルールに基づいた ZIP ファイルです。ZIP ファイル(と APK)の中にあるほとんどのコンテンツは、Deflate と呼ばれるテクノロジーを使って圧縮されています。Deflate はデータの圧縮には優れていますが、元の(圧縮されていない)コンテンツの変更点を特定するのが非常に難しくなるという欠点もあります。元のコンテンツをわずかに変更しただけでも(本の中の 1 語だけ変更するように)、Deflate が出力する圧縮データは まったく異なるものに見える場合があります。 元の コンテンツの差分を作るのは簡単でも、 圧縮された コンテンツの差分を作るのはとても難しいため、パッチは非効率になってしまいます。
左側の圧縮されていないテキストを 1 文字変更しただけで、右側の圧縮されたテキストがどのくらい変わるかをご覧ください。
そのため、ファイルごとのパッチは、圧縮されていないデータで検出された差分に基づきます。パッチの生成にあたって、まず古いファイルと新しいファイルの両方を解凍し、差分を計算します(ここでは、まだ bsdiff を利用しています)。次に、パッチを適用するため、古いファイルを解凍して圧縮されていないコンテンツに差分を適用し、新しいファイルを再圧縮します。その際に、端末上の APK が Play Store 上の APK とバイト単位で完全に一致していることを確認する必要があります(この理由については、APK 署名スキーマ v2 をご覧ください)。
新しいファイルの再圧縮には、2 つの問題があります。1 つ目の問題は、Deflate の設定によって Deflate の出力が色々と変わることです。そもそも、圧縮の際にどのような設定が使われたのかはわかりません。2 つ目は、Deflate には多くのバージョンが存在しており、ユーザーの端末上にある Deflate が適切なバージョンか確認する必要があります。
幸運にも、Play Store のアプリを分析したところ、Play Store のほぼすべての Deflate コンテンツで、zlib(もっとも普及している Deflate ライブラリ)に基づいた、互換性がある最近のバージョンの Deflate が使われていることがわかりました。さらに、実質的に使われている設定は、デフォルト(level=6)と最大(level=9)の圧縮設定だけでした。
以上のことを踏まえると、元々の Deflate 設定を検出して再現できると言えます。つまり、データを解凍し、パッチを適用してデータを再圧縮し、元々アップロードされたものと まったく同じバイト列 を作ることができます。
ただしこの方式には、端末側で必要な処理能力が高くなるという欠点もあります。最近(たとえば、2015 年以降)の端末では、再圧縮には 1 メガバイトあたり 1 秒少しかかり、古い端末や能力が低い端末はさらに時間がかかります。現時点の分析によると、平均で、パッチのサイズが半分になるとパッチの適用(再圧縮を含めたファイルごとのパッチ適用)にかかる時間は倍になります。
今のところ、この新しいパッチ テクノロジーの利用は自動アップデートのみに制限しています。これは通常、夜間にスマートフォンが電源に接続され、ユーザーが使用していない可能性が高いときにバックグラウンドで行われるアップデートです。これによって、ユーザーが手動でアプリをアップデートする際に、いつもより長く待たなければならないという事態を回避しています。
ファイルごとのパッチ適用の効率性
以下に、すでにファイルごとのパッチ適用を使っているアプリのアップデートの例を示します。
アプリ
|
元のサイズ
|
以前の(bsdiff)パッチサイズ
(元のサイズに対する割合)
|
ファイルごとのパッチによるサイズ(元のサイズに対する割合)
|
71.1 MB
|
13.4 MB(-81%)
|
8.0 MB(-89%)
| |
32.7 MB
|
17.5 MB(-46%)
|
9.6 MB(-71%)
| |
17.8 MB
|
7.6 MB(-57%)
|
7.3 MB(-59%)
| |
18.9 MB
|
17.2 MB(-9%)
|
13.1 MB(-31%)
| |
52.4 MB
|
19.1 MB(-64%)
|
8.4 MB(-84%)
| |
16.2 MB
|
7.7 MB(-52%)
|
1.2 MB(-92%)
|
データを節約してユーザー(そしてデベロッパー)をハッピーに
以上の変更は、10 億人以上の Android ユーザー コミュニティが、最小限のデータ量でアプリの定期アップデートを行えるように設計されています。一番の長所は、デベロッパーは何もする必要がないことです。このアップデートのサイズ削減は、無償で行われます。
技術的な詳細など、ファイルごとのパッチ適用についてさらに詳しく知りたい方は、Archive Patcher GitHub プロジェクトをご覧ください。ソースコードを含む情報を閲覧できます。ファイルごとのパッチ適用は、完全なオープンソースです。
APK サイズをさらに削減したいデベロッパーの方は、APK サイズ削減のための一般的な推奨事項もご覧ください。
Posted by Khanh LeViet - Developer Relations Team