Androidのパフォーマンスのヒントから「Intだけが必要な場合はEnumを回避する」が削除されたのはなぜですか?


175

「Intのみが必要な場合は列挙型を回避する」セクションが公式開発者向けドキュメントから削除されました。(古いセクションの内容については、Androidがenumを使用しない理由を参照してください)

どうして?ヒントを廃止したAndroid VMの変更はありましたか?


2
参考までに、Shrubberyの例の逆コンパイルされたバイトコードは次のとおりです。https
Josh Lee

15
2014年3月の時点では、以下のページには、まだ使用して列挙型に対するアドバイスが含まれています:developer.android.com/training/articles/memory.html#Overhead
タヒルアクタール

2
1年後、@ TahirAkhtarが言ったように、Androidの公式トレーニングでは、「Androidでの列挙型の使用は絶対に避けるべきです」と述べています。
LarsH 2015年

1
回避列挙に勧告を注意することは興味深いリードAndroidの開発者から、この2015年の記事である:medium.com/google-developers/... も:「AndroidのメーカーとのGradle 1.3以降でサポートされて@IntDef注釈を、使用していることを注意、 int変数を使用することによるサイズとパフォーマンスの利点を維持しながら、コードのビルド時の型安全性(lintエラーが有効な場合)を提供します。」
tonylo

4
2018年4月の時点で、次のページには列挙型の使用に対するアドバイスが含まれていません。developer.android.com/topic/performance/memory#Overhead
Robin Davies

回答:


157

そのドキュメントの元のバージョンは偏見の集まりでした。実際のベンチマークでバックアップされたファクトのみを含むように書き直され、VMが更新されると更新されます。http://code.google.com/p/dalvik/で、さまざまなベンチマークに加えて、コアライブラリの最適化に使用するいくつかのベンチマークを見つけることができます。


35
SOプロファイルに資格情報をリストした場合に役立ちます。少し掘り下げてみました。しかし、あなたがVMチームで働いているように見えるので、私はあなたの答えを公式の答えとして受け入れます。:)
ティエリーディミトリロイ

25
enumクラスを追加すると、もちろんアプリに追加のクラスが含まれることになるため、無料ではありませんが、開発者はenumを便利な場所にのみ追加していると想定する必要があります。enumについて私が見た唯一の本当に悪い使い方は、(ビットマスクなどの)intが本当に必要ないくつかの調和コードであり、「enum」は合理的な意味でのenumではありませんでした。「ordinal()」を何度も呼び出している場合は、おそらく悪臭であり、列挙型を必要としません。しかし、これはAndroid固有のヒントではなく、いずれにしても非常にまれなデザインエラーです。
エリオットヒューズ

17
、この文書の日付のうちにもティエリ・DimitriRoy @は?具体的には、Androidでの列挙型の使用を厳密に回避する必要が
Jacob Tabak

3
FWIW、Proguardはデフォルトで列挙型をintに変換します。
ナチョコロマ

11
あなたが与えたリンクは死んでいます。
Terry、

26

推測:

  • HummingbirdやSnapdragonなどのギガヘルツCPUが一般的になり、Dalvik VMを元々制約していた小さなコードの小さなメモリ要件は、もはや真実ではなくなりました。
  • すべての出荷デバイスはJITを使用します(2.2の新規)。列挙型のクラス初期化子はより高速に実行され、値はJIT時間定数として扱われる可能性があり、JITは列挙型クラスの効率化を特別にサポートしている可能性があります。
  • 本当にパフォーマンスに敏感なコードはNDKを使用します。NDKは、Android 1.5がリリースされたときにまだ新しく、洗練されていませんでした。2.3のNDKは、ほぼ完全に管理されていないゲームを可能にするネイティブアクティビティをサポートしています。

したがって、GUIアプリの比較的平凡な要件の場合、列挙型の開発時の利点は、追加のランタイムコストをはるかに上回ります。


23

Elliott Hughesは、彼のブログでドキュメントの書き換えに関する詳細を公開しています。http//elliotth.blogspot.com/2010/09/java-benchmarks.html

投稿の後半では、パフォーマンスドキュメントに関するすべての申し立てがベンチマークでバックアップされていることを説明しています。以前のバージョンのドキュメントには、「列挙型は高すぎるため、列挙型を避けてください」などの未検証の主張が含まれていたようです。


エリオットの受け入れられた答えをこのリンクで補足したかっただけです。
jkooker

12

Elliot Huguesの2011年の回答によると、列挙型を回避する最初の理由は、「処理パフォーマンス」の場合のように、パフォーマンス上の理由によるとのことです。この理由は事実に裏付けられていないため、公式ドキュメントから削除されました。

enumは整数を使用するよりも多くのデータをメモリに追加するため、後で追加されました。


2
さらに、Googleの人たちはIntDefアノテーションを導入しました。これにより、Android Studioのエラーと警告でint定数を安全に使用できます。blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.

9

TLDR: Dalvikはメモリ割り当てに問題がありEnum、よりも多くのメモリを使用していますint。Android Lollipopは、Dalvikを、同じ制限の影響を受けないARTに置き換えました。したがって、この推奨事項はもはや関係ありません。

長い答え:

うわー!8年後、5つの回答と多くのコメントの後、本当の理由はまだ対処されていません。

Androidのロリポップ以前の時代には、DalvikがVMのプロセスとして使用されていました。その間、アプリケーションで使用できるメモリは少量だったため、Dalvikには多くのメモリ制約がありました。メモリ割り当てのために、Dalvikはヒープをウォークしてスペースを見つける必要がありました。ヒープも時間とともに断片化します。Dalvikはデフラグできなかったため、時間の経過とともに割り当てられ、最終的にスペースが不足しました。

Intのみが必要な列挙型を回避する

ためのDalvikの日から来てEnumより多く大きいintとメモリの割り当ては非常に高価でした。

今日、早送りして、DalvikはARTに置き換えられました。ARTはKitKatでリリースされ、Lollipop以降のデフォルトです。

ARTは、メモリを最適化するためではなく、パフォーマンスを最適化するためにゼロから作成されました。また、割り当てとコレクション用に最適化されています。その理由は、大きなオブジェクト用にメモリが確保されているためです。すべてを同じヒープに配置し、すべての小さなオブジェクトの中で大きなオブジェクト用のスペースを見つける必要がある代わりに、ARTはすべての大きなオブジェクトとビットマップを別のヒープに配置します。そして、小さなオブジェクトは別のヒープに入ります。また、最適化することもできます。

ARTの後、EnumAndroid を使用するかどうかは問題ではありません。そのため、現在、推奨はありません。

これはGoogleのChet Haaseによるものです。私は彼のGoogle I / Oの話を見つけてビデオ全体を見ることをお勧めします。Androidに関する多くの有用な情報と洞察が含まれています。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.