コンテキスト
最近、航空機のダウンロードビデオの遅いバグを扱うとき、同僚のフィードバックによると、無視されている問題を発見し、値の列挙()このメソッドの巨大なピット!列挙として航空機のプッシュを解析するため、同社のプロジェクトのコードのように、コードは列挙の様々な、通常はこのように書かれています:
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()::の呼び出しを最小限に抑えるしかありません。
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;
}
測定
まとめ
values()の通常の使用は、この問題があるとは思わなかったので、目的は、外部ユーザーがそれを変更することを許可しないようにする必要がありますが、明らかにまた、能力のいくつかを制限し、呼び出し側として、この頻繁に使用される機能、または権利を理解するためにソースコードに深く入ること。




