blog

パフォーマンスの最適化 - 列挙値()の落とし穴

一見すると、それは何もないように見えますが、航空機に接続した後、高周波プッシュの多数のデータのすべての種類は、この値()メソッドが何度も呼び出され、実際のテストでは、明らかなメモリジッタ現象が発生しま...

May 8, 2020 · 2 min. read
シェア

コンテキスト

最近、航空機のダウンロードビデオの遅いバグを扱うとき、同僚のフィードバックによると、無視されている問題を発見し、値の列挙()このメソッドの巨大なピット!列挙として航空機のプッシュを解析するため、同社のプロジェクトのコードのように、コードは列挙の様々な、通常はこのように書かれています:

 enum Number {
 /**
 * テスト例
 */
 ONE(0),
 TWO(1),
 THREE(2),
 FOUR(3),
 FIVE(4),
 SIX(5),
 SEVEN(6);
 private int value;
 Number(int value) {
 this.value = value;
 }
 public int value() {
 return this.value;
 }
 public boolean equals(int b) {
 return value == b;
 }
 // 値に基づいて列挙を検索するfindメソッドを実装した。
 public static Number find(int value) {
 Number result = ONE;
 for (int i = 0; i < values().length; i++) {
 if (values()[i].equals(value)) {
 result = values()[i];
 break;
 }
 }
 return result;
 }
 }

一見それは何もないように見えますが、航空機に接続した後、データの様々な種類の高周波プッシュの数が多い、この値()メソッドが何度も呼び出され、実際のテストでは、明らかなメモリジッタ現象が発生します。

分析

列挙分析

オンライン調査から Javaの列挙型と Javaの列挙値のメソッドの 深い理解は 、コピー操作です、知っていますか?そして、私自身の逆コンパイルの結果:

values()メソッドの列挙は確かにコピーメソッドであり、各呼び出しは、新しい配列を生成しますが、配列のメンバは、より多くのメモリを占有しませんが、新しい配列自体が(メモリ内のJavaオブジェクトの構造)スペースの一定量を占有することです。

解決方法

この場合、values()::の呼び出しを最小限に抑えるしかありません。

 private static Number[] values;
 
 // キャッシュを使用する
 public static Number newFind(int value) {
 Number result = ONE;
 if (values == null){
 values = values();
 }
 for (int i = 0; i < values.length; i++) {
 if (values[i].equals(value)) {
 result = values[i];
 break;
 }
 }
 return result;
 }

測定

2つの関数を実装し、それぞれのメモリ使用量を連続10タップで検証します:
10回操作すると、メモリのジッターがあることがはっきりわかります。
10回操作した後は、CPU使用率が下がるなど、基本的に目立った変化はありません。

まとめ

values()の通常の使用は、この問題があるとは思わなかったので、目的は、外部ユーザーがそれを変更することを許可しないようにする必要がありますが、明らかにまた、能力のいくつかを制限し、呼び出し側として、この頻繁に使用される機能、または権利を理解するためにソースコードに深く入ること。

Read next

Js型判定

typeof typeof は単項演算子で、オペランドの前に置かれます。戻り値は、オペランドの型を表す文字列です。 typeof の機能の範囲 typeof は、null 以外のすべての基本クラスを正しく判定することができます。

May 8, 2020 · 4 min read