2016-01-08 18 views
5

は、私は次のコードを持っていると言います。しかし、リテラル値を処理しているので、コンパイラはプリミティブリテラルをボックスリテラルに置き換えることができるので、余分なランタイムオーバーヘッドはありません。プリミティブリテラルのオートボックスにはパフォーマンスコストはありますか?理論的に</p> <pre><code>Map<String, Boolean> map = ... map.put("foo", true); </code></pre> <p>、<code>true</code>は<code>Boolean.TRUE</code>を挿入対ヒットわずかなパフォーマンスが得られ、autoboxedする必要があります:

誰かが私を攻撃する前に、パフォーマンスのコストがわずかであっても、コードの明快さのために原始的なリテラルを選択します。この質問は主に理論的なものです。

+0

パフォーマンス関連の質問を理解するための鍵は、常にテストから始まります。あなたの質問を改善するために、パフォーマンス分析の結果を示すタイミングテストを示してください。たとえば、100Kのエントリをマップに入れ、それがどれくらいかかったかを出力するタイミング付きfor-loopを書くことができます。また、 'map.put'の異なる引数についても同じことを実行します。 – activedecay

+0

' Boolean'定数を使うことができます。 'map.put(" foo "、Boolean.TRUE);' –

+0

@ElliottFrisch私は知っています。私の質問は、それがまったく助けになるかどうかです。 – shmosel

答えて

4

はい、パフォーマンスが低下します。プリミティブをボックスするには、ラッパータイプのvalueOf()メソッドが使用されます。これはBooleanreturn x ? TRUE : FALSE;)のような簡単な方法であるため、JITは結果を効果的にインライン化することができます。しかし、現在Javaコンパイラは、そうではありません。 (valueOf()の使用はJLSでは必須ではないため、Booleanの最適化を導入することができます)。

他のタイプの場合は、より複雑です。たとえば、Integerは、ゼロに近い値のキャッシュされたインスタンスを返し、より大きな値の新しいインスタンスを作成します。最適化は引き続き実行できますが、新しいインスタンスの割り当てには常に時間がかかります。コメントに応えて


、私は疑問のキーポイントであることを要したものに焦点を当ててみましょう:私たちはリテラル値を扱っているので、

、コンパイラのことが可能です箱入りリテラル

はい、それは可能で、しかしなしとプリミティブリテラルを置き換えるために、オラクルjavacコンパイラはトンを行いません。彼の

重要ですか?いいえ、Booleanへのボクシングのパフォーマンスヒットは極微です。 box boolean他のプリミティブと同じvalueOf()テクニックを使用することは、コンパイラにとって安全で純粋な選択です。

+0

JITがインライン化できず、両方のオプションを本質的に同等にすることができない場合、私は驚くでしょう。 。 – assylias

+0

@assylias私も驚いていますが、最初の実行では起こりますか?たとえそれがあったとしても、最適化プロセスは 'true'の代わりに' Boolean.TRUE'を使用したコードに比べて時間がかかりますか? – erickson

+3

主なポイントは、*新しいオブジェクト*を割り当てる必要があるときはいつでも、メインのパフォーマンスヒットが発生するということです。 Boolean.valueOf()の場合、新しいオブジェクトは決して割り当てられません。このコードでは、booleanプリミティブリテラルではなく、クラス定数Boolean.TRUEを実際に使用する必要がありますが、この場合の実際のパフォーマンスの差は、 – scottb

関連する問題