17

Javaのクラスとdoubleのプリミティブ型のパフォーマンスの違いに興味がありました。そこで、少しベンチマークを作成し、クラス型がプリミティブ型より3倍から7倍遅いことを発見しました。(ローカルマシンOSXでは3倍、ideoneでは7倍)

テストは次のとおりです。

class Main {
    public static void main(String args[]) {
        long bigDTime, littleDTime;

        {
            long start = System.nanoTime();
            Double d = 0.0;
            for (Double i = 0.0; i < 1432143.341; i += 0.1) {
                d += i;
            }
            long end = System.nanoTime();
            bigDTime = end - start;
            System.out.println(bigDTime);
        }

        {
            long start = System.nanoTime();
            double d = 0.0;
            for (double i = 0.0; i < 1432143.341; i += 0.1) {
                d += i;
            }
            long end = System.nanoTime();
            littleDTime = end - start;
            System.out.println(littleDTime);
        }

        System.out.println("D/d = " + (bigDTime / littleDTime));
    }
}

http://ideone.com/fDizDu

では、なぜダブルタイプはそれほど遅いのですか?数学演算子を許可するように実装されているのはなぜですか?

4

3 に答える 3

22

では、なぜダブルタイプはそれほど遅いのですか?

値は、割り当て、割り当て解除、メモリ管理に加えてゲッターとセッターを必要とするオブジェクト内にラップされているため

数学演算子を許可するように実装されているのはなぜですか?

autoboxは、それらが単純な値ではないという事実を心配することなく、そのようなラッパーを使用できるようにすることを目的としているためです。あなたは持っていることができないことを好みますArrayList<Double>か?パフォーマンスは必ずしも必要ではなく、状況に応じて3倍から7倍のパフォーマンスの低下が許容される場合があります。最適化は常に存在するとは限らない要件です。

これはすべての状況に当てはまります。LinkedListランダムアクセス要素を使用するのはやり過ぎかもしれませんが、これはまったくLinkedList実装すべきではないという意味ではありません。これは、いくつかのランダムアクセスにリンクリストを使用すると、パフォーマンスが大幅に低下する可能性があることを意味するものでもありません。

最後の注意:そのようなことをベンチマークする前に、VMをウォームアップさせる必要があります。

于 2013-03-23T03:21:04.047 に答える
8

Double通常は、、などを使用しませんInteger(場合によってIntegerは、「オプション」の値を保存すると便利な場合があります。場合によっては使用することもできます。これらの値を使用できるためnull、この可能性は低くなります。)DoubleNaN

その理由Doubleは次のとおりです。Javaには、主に2つのタイプの値があります。オブジェクト(基本的には算術演算のないC / C ++ポインターのようなもの)とプリミティブ値(例double)です。のようなクラスArrayListは、任意のを受け入れるように定義Objectできます。これにより、ユーザーは、、または好きなものを1つに格納できますがStringFileのようなプリミティブ値はそのようなdouble定義ではカバーされません。したがって、のようなクラスは、の作成者がすべてのプリミティブ型の特別なバージョンを作成する必要なしに、のようなクラスがsを格納Doubleしやすくするために存在します。ArrayListdoubleArrayList

于 2013-03-23T03:26:19.080 に答える
4

Double箱入りdoubleです。したがって、一般に、コンパイルされたコードは、それを使用Doubleして何かを行う前に、nullをチェックする必要があります。もちろん、これは何もしないよりも遅いです。

Double(およびプリミティブの他のボックス化されたバージョン)は、であるため便利ですObject。これにより、を取得する関数に渡し、別の場所Objectにキャストして戻すことができDoubleます。さらに便利なことに、ジェネリック型にそれを含めることができます。ジェネリック型には、doubleまたはその他のプリミティブを含めることはできませんが、を含めることはできますDouble

于 2013-03-23T03:26:00.130 に答える