web-dev-qa-db-ja.com

Javaパフォーマンス:trueとBoolean.TRUE

パフォーマンスと効率的なメモリ使用量の点で優れているのは次のうちどれですか?

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return Boolean.TRUE
}

Boolean isItTrue(arg){
    return true;
}

boolean isItTrue(arg){
    return true;
}

プリミティブ型を操作する方が速くて簡単なはずですが、一方で、静的オブジェクトへの参照を使用する場合、新しい値は作成されません。または、コンパイラレベルで最適化され、すべてのtruefalseが、メモリを節約するために静的オブジェクトへの参照に置き換えられていますか?

28
Dima

まず、他のものよりもいずれかを使用することのパフォーマンス上の利点は、おそらく小さすぎて関連性がないことです。コードの単純さ/読みやすさ/保守性ははるかに重要です...ほとんどの場合。


いずれの例にも、Booleanインスタンスの作成は含まれていません。理論的には、4つのうち3つがBooleanクラスの初期化をトリガーする可能性があります...そして、アプリケーションがそれを行わなかった可能性があります。その非常にありそうもないイベントでは、アプリケーション全体が、他の方法では割り当てられなかった2つのオブジェクトを割り当てます。


これは、レジスタをゼロに設定するだけなので、他のすべてと同等かそれよりも高速になります。

_boolean isItTrue(arg){
    return true;
}
_

単独で考えると、これはレジスタをゼロにするのではなく、メモリから静的参照をロードする必要があります。ただし、状況によっては、JITコンパイラーがこれを最適化できる場合があります。

_Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}
_

表面的には、これにはBoolean.valueOf(true)を呼び出してtrueを「ボックス化」する必要がありますが、JITコンパイラはインライン化することで前のコードと同じコードに最適化できるはずです。呼び出し。

_Boolean isItTrue(arg){
    return true;
}
_

表面的には、これにはBoolean.booleanValue(Boolean.TRUE)を呼び出してBooleanを「ボックス化解除」することが含まれます。この呼び出しはインライン化できます。 JITコンパイラがBooleanオブジェクトへの参照のロードとその値フィールドのフェッチを回避できる可能性もあります。

_boolean isItTrue(arg){
    return Boolean.TRUE
}
_

結論として、4つの選択肢の相対的なパフォーマンスは、JITコンパイラーが最適化にどれだけ成功するかによって異なります。これは、コンテキスト、JITコンパイラの詳細、JVM設定などによって異なります。最良の場合、JITコンパイラーは(少なくとも理論的には)それらすべてに対して同じ(最適な)コードを生成できます。

24
Stephen C

パフォーマンスが向上したとしても、それはごくわずかであり、無関係です。 Boolean.TRUEおよびBoolean.FALSEは、どのような場合でも新しいオブジェクトを返しません。

11
Jim

このようなマイクロ最適化よりも、コードメンテナの明確さを優先してください。問題は「どちらが小さい/速いか」であってはならず、最初にあなたが何を意味するかを表現します。

メソッドがブールオブジェクトを返す場合、受け取った人は誰でも、それがnullである可能性があるかどうかを判断する必要があります。また、それがis nullである場合は、「わからない」.

したがって、ブール値の型を返します。それが意味する場合は、それ以外の場合は、Nullを許可し、次にブール値を許可します。

ブール値を返す場合は

return true; // or false

パフォーマンスだけでなく明確さのためにも、オートボクシングに頼るよりも優れている必要があります。

ブール値を返す場合は

return Boolean.TRUE

私がマイクロ最適化に反対しているのと同じように、それは余分なゴミを作成することを回避するだけです。戻り値の型と著しく一致しているという点でも、より明確であると私は主張します。

9
djna

彼らははるかに速くなります。この2つに違いはないと思います。

Boolean isItTrue(arg){ 
    return Boolean.TRUE;
}

boolean isItTrue(arg){
    return true;
}

ただし、他の実装は、バックエンドでボックス化およびボックス化解除を行うため、プロセッサに時間がかかるため、速度が低下します。


編集

私は4つの異なる方法を実装することによっていくつかの事実を収集しました。ただそれをあなたと共有したいのですが、それを書く方法であるかどうかはわかりません。

Boolean isItTrue(){ 
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.844
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return Boolean.TRUE;
}

Free Memory before start --> 16030936
Time taken in Secs --> 10.109
Free Memory After Process --> 15940472
Memory Usage --> 90464

Boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.906
Free Memory After Process --> 15940472
Memory Usage --> 90464

boolean isItTrue(){
    return true;
}

Free Memory before start --> 16030936
Time taken in Secs --> 7.828
Free Memory After Process --> 15940472
Memory Usage --> 90464

メインクラス

public static void main(String[] args){
    NewClass n = new NewClass();

    long sysTime = System.currentTimeMillis();

    Runtime rt = Runtime.getRuntime();
    long freeMem = rt.freeMemory();
    System.out.println( "Free Memory before start --> " + freeMem );
    for( int i = 0; i < Integer.MAX_VALUE; i++ ){
        n.isItTrue();
    }
    System.out.println( "Time taken in Secs --> " + (System.currentTimeMillis() - sysTime)/1000D);
    System.out.println( "Free Memory After Process --> " + rt.freeMemory() );
    System.out.println( "Memory Usage --> " + ( freeMem - rt.freeMemory() ) );
}
7

最後のもの

boolean isItTrue(arg){
    return true;
}

メソッドが時々Booleanを返す必要がある場合にのみ、nullを使用します

3
Manuel Selva

その論理により、静的オブジェクト自体への参照は、それ以上ではないにしても、真理値と同じくらいコストがかかります。

オブジェクトの使用はプリミティブよりも多少遅いかもしれませんが、心配する必要はありません。違いは関係ありません。

2
slezica

最後のものを使用します(booleanだけ)。コンパイラーがそれらすべてを同じものに最適化したとしても、少なくともコンパイラーの仕事を簡単にしていることになります(あなたが知っている簡単な仕事ではありません!)。

さらに、キーストロークが少なくなります(Shiftキーを押す必要はありません)。しかし実際には、ラッパークラスを使用する必要がある唯一の理由は、ラッパークラスをnullに設定する機能が必要な場合、およびLinkedList<E>などの汎用データ構造で使用する場合です。

2
tskuzzy

私の経験則は次のとおりです。

  1. デフォルトの選択はプリミティブ型(boolean)です。
  2. Null可能性が必要な場合、または値をコンテナーに格納する必要がある場合は、クラス(Boolean)を使用します。

これを念頭に置いて、私のデフォルトの選択は次のようになります。

boolean isItTrue(arg){
    return true;
}

パフォーマンスに関する限り、確かに思われる唯一のことは、Booleanを使用することがbooleanを使用するよりも速いになるシナリオを想像するのは難しいということです。遅くなるか同じになるかは多くのことに依存し、一般的に答えることは不可能です。

これが本当に気になる場合は、重要な場所でコードをプロファイリングしてください。

1
NPE

Java.lang.Booleanは16バイトを取ります。

これは、パフォーマンスとメモリサイズの問題のみを探している場合の方法です。

boolean isItTrue(arg){
    return true;
}
0