質問

なぜコードの第二の部分が速いのですか?

Map<Integer, Double> map = new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {
        map.put(i, j);
    }
}

Map<Integer, Double> map=new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {            
        map.put(new Integer(i), new Double(j));
    }
}
役に立ちましたか?

解決

はオートボクシングは、内部整数デフォルト-128 127によって(小さな整数用のオブジェクトキャッシュInteger.valueOfを使用するが、最大値を「java.lang.Integer.IntegerCache.high」プロパティを使用して構成することができる - のソースコードを参照してくださいInteger.valueOf)ので、直接new Integerを呼び出すと異なっています。 Integer.valueOfnew Integerを呼び出す前に、整数値の大きさのための簡単なチェックを行いますので、それは(あなたが小さな整数の多くを持っている場合、それはより多くのメモリを使用していますが)直接new Integerを呼び出すために少し高速です。 Javaでの割り当ては非常に高速で、かつGCは非常に高速でもあるので、GCを行う時間は、ライブ短命オブジェクト(ごみの量に比例しないすなわち)の数に比例します。

しかし、最適化が有効になっているJVMのバージョンとに応じて、最適化を行うことができないというあなたの例では短命オブジェクトを(割り当てる際におけるはるかに大きなパフォーマンスの違いを作り出すことができるスカラー交換の最適化は、ので、そこにあります)あなたがマップ内のオブジェクトを格納しているが、他の多くの状況で、それは便利です。

は、最近のJVMのバージョンでスカラー交換の最適化は、(そこにありますエスケープ解析は一時的に無効にするです)1.6.0_18を除き、どの手段短命オブジェクトの割り当てが離れて最適化することができます。 JVMでのスカラー置換が新しかったとき、誰かが作っあなたのようなコードがあったベンチマークする。結果は、プリミティブを使用したコードは、最速だった明示的なnew Integer()呼び出しでコードがほぼ同じ速プリミティブを使用して1、及び使用済みのオートボクシングはかなり遅かったコードのようだったということでした。オートボクシング用途はInteger.valueOfので、これがあって、再度少なくともスカラー交換の最適化を考慮に特別な場合を取りませんでした。私は最適化はそれ以来改善されているかどうかわからない。

他のヒント

オートボクシングはInteger.valueOfDouble.valueOfを使用します。 (それが最終的にインライン展開されますが)いくつかのオーバーヘッドはこれらのメソッドを呼び出すことです。またInteger.valueOfは、(それがヒープサイズを少し減らすことができるが)低値が頻繁にあなたのコードでの勝利ではないプールされたインスタンスを、使用するためのいくつかのチェックを行います。プールされたインスタンスは、彼らは、GC時間をヒープサイズを小さくしても、平等のテストのパフォーマンスを向上させる可能性が勝つかもしれ..

しかし、一般的に、それはあなたが、一般的には、無視すべきmicrooptimisationです。

マイクロベンチマークの結果は信頼できないので?

また、オートボクシングはInteger.valueOf()とは、Double.valueOf()、しないコンストラクタを使用して実行されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top