2013-03-23 13 views
12

Ich war neugierig, was die Performance-Unterschiede zwischen Java-Klasse und Urtyp für Doppel waren. Also habe ich einen kleinen Benchmark erstellt und festgestellt, dass der Klassentyp 3x-7x langsamer ist als der primitive Typ. (3x auf dem lokalen Rechner OSX, 7x auf ideone)Java Doppel vs double: Klasse Typ vs Urtyp

Hier ist der Test:

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

Warum ist der Double-Typ so viel langsamer? Warum wird es überhaupt implementiert, um mathematische Operatoren zu ermöglichen?

+1

Es ist langsam wegen der Notwendigkeit zu boxen und zu entpacken. Dies ist das erwartete Verhalten. –

+0

@HovercraftFullOfEels Das macht Sinn, aber es scheint immer noch eine Menge Overhead. –

+1

Es ist eine Menge Overhead. Aus diesem Grund sollten Sie die Verwendung primitiver Wrapper-Typen in zeitkritischem Code vermeiden. –

Antwort

17

Warum ist der Double-Typ so viel langsamer?

Da der Wert innerhalb eines Objekts gewickelt ist, die Zuordnung muss, Deallokation, Speicherverwaltung sowie Getter und Setter

Warum ist es sogar mathematische Operatoren ermöglichen umgesetzt?

Da Autobox soll Ihnen ermöglichen, solche Wrapper zu verwenden, ohne sich Gedanken über die Tatsache, dass sie keine einfachen Werte sind. Möchten Sie nicht ArrayList<Double> haben? Leistung ist nicht immer notwendig und ein Tropfen von 3x-7x der Leistung je nach Situation vielleicht akzeptabel. Optimierung ist eine Anforderung, die nicht immer vorhanden ist.

Dies ist in jeder Situation wahr, mit einem LinkedList auf Random Access-Elemente könnte Overkill sein, aber dies bedeutet nicht, dass LinkedList sollte überhaupt nicht implementiert werden. Dies bedeutet auch nicht, dass die Verwendung einer verketteten Liste für einige zufällige Zugriffe die Leistung so stark beeinträchtigen könnte.

Eine letzte Anmerkung: Sie sollten die VM vor dem Benchmarking solche Dinge aufwärmen lassen.

3

Double ist ein boxed double. Daher muss der kompilierte Code im Allgemeinen Double auf Null überprüfen, bevor Sie irgendetwas damit machen. Das ist natürlich langsamer als nichts zu tun.

Double (und andere Box-Versionen der Primitiven) ist nützlich, weil es eine Object ist. Dies ermöglicht es Ihnen, es an Funktionen zu übergeben, die eine Object nehmen würden, und es an anderer Stelle zurück zu Double zu werfen. Nützlicher ist, dass generische Typen es enthalten können: Ein generischer Typ kann double oder ein anderes primitives Element nicht enthalten, aber er kann ein Double enthalten.

8

Sie würden normalerweise nicht verwenden Double, Integer usw. (Gelegentlich Integer usw. kann nützlich sein, einen ‚optional‘ Wert zu speichern -. Sie könnten es null manchmal sein wollen Dies ist weniger wahrscheinlich mit Double weil NaN ist für diejenigen.)

Der Grund Double existiert, ist wie folgt. Java hat zwei Haupttypen von Werten: Objekte (im Wesentlichen wie C/C++ Zeiger ohne die Arithmetik) und Grundwerte (z. B. double).Klassen wie ArrayList können so definiert werden, dass sie Object akzeptieren, was es Benutzern ermöglicht, String, File oder was auch immer in einem zu speichern - aber primitive Werte wie double fallen nicht unter eine solche Definition. Daher gibt es Klassen wie Double, um Klassen wie ArrayList das Speichern von double s zu erleichtern, ohne dass die Autoren von ArrayList spezielle Versionen für alle primitiven Typen erstellen müssen.