web-dev-qa-db-ja.com

Java Double vs double:クラスタイプvsプリミティブタイプ

私は、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/fDizD

では、なぜDouble型がそれほど遅いのでしょうか。なぜ数学演算子を許可するために実装されているのですか?

17
Patrick Lorio

では、なぜDouble型がそれほど遅いのでしょうか。

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

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

Autoboxは単純な値ではないという事実を心配せずにそのようなラッパーを使用できるようにすることを意図しているためです。 ArrayList<Double>を使用できないようにしますか?パフォーマンスは常にではない必要であり、状況に応じて3x-7xのパフォーマンスの低下が許容される可能性があります。最適化は常に存在するとは限らない要件です。

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

最後の注記:ベンチマークの前にVMをウォームアップする必要があります。

22
Jack

通常、DoubleIntegerなどは使用しません(「Integer」などは、「オプション」の値を格納するのに役立ちます。nullにしたい場合があります。Doubleでは、NaNを使用できるため、これはあまりありません。 )

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

8
entheh

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

Double(およびプリミティブの他のボックス版)は、Objectであるため便利です。これにより、Objectを受け取る関数に渡し、Doubleにキャストし直すことができます。さらに便利なことに、ジェネリック型にそれを含めることができます。ジェネリック型にはdoubleまたは他のプリミティブを含めることはできませんが、Doubleを含めることはできます。

4
user2201345