2010-04-07 9 views
27

Ich muss eine Kopie eines bestimmten Datums 100-mal machen (ich kann nicht per Referenz übergeben). Ich frage mich, welche der folgenden zweicalendar.getInstance() oder calendar.clone()

newTime=Calendar.getInstance().setTime(originalDate); 

ODER

newTime=originalDate.clone(); 

Leistung conern ist hier bessere Möglichkeiten sind der Haupt.

thx.

+1

warum nicht nur Test und beide Fälle Profil? – Tedil

+0

Ich könnte aber das Problem ist, wenn ich einen gültigen Komponententest schreiben kann. Ich lese, dass der Klon() langsamer ist als der neue Operator (bei Verwendung von JIT) in Java 1.4 ich glaube ... ich konnte nicht finden, wenn dies in Java 5 und später ... –

+5

'Kalender # setTime (Date)' zurückgibt 'void', Ihr Beispiel ist nicht gültig – yegor256

Antwort

26

würde ich

newTime= (Calendar) originalDate.clone(); 
+20

Warum würden Sie es anstelle eines "neuen" verwenden? – pnt

+15

Sie vergessen die (Kalender) Besetzung Ich denke – tviana

+2

'originalDate.clone();' bietet Ihnen die 'Ansicht'. Daher müssen wir es in Calendar umwandeln wie @tviana erwähnt: 'Calendar newTime = (Kalender) originalDate.clone();' – ArtiomLK

1

Mein Ansatz für die Option 1) und dann sicherstellen, dass die Anwendung gründlich Engpässe zu überprüfen ist profiliert, um zu gehen wäre zu verwenden. Es kann sein, dass der obige Code überhaupt kein Problem in der Gesamtleistung der Anwendung am Ende des Tages ist.

30
  1. Mein Darm sagt mir, dass Clone() schneller sein wird.
  2. Warum versuchen Sie es nicht mit einem schnellen Benchmark [*]?
  3. Verwenden Sie nur den langen Wert date.getTime(), wenn Sie keine Kalenderberechnungen durchführen müssen.

[*]

private static final int N = 100000; 

public static void main(final String[] args) throws Exception { 

    final Date date = new Date(); 

    { 
     final long start = System.currentTimeMillis(); 
     for (int i = 0; i < N; i ++) { 
      final Date date2 = (Date) date.clone(); 
     } 
     final long end = System.currentTimeMillis(); 
     System.out.println("Clone: " + (end - start) + " ms"); 
    } 
    { 
     final long start = System.currentTimeMillis(); 
     for (int i = 0; i < N; i ++) { 
      final Calendar cal = Calendar.getInstance(); 
      cal.setTime(date); 
      final Date date2 = cal.getTime(); 
     } 
     final long end = System.currentTimeMillis(); 
     System.out.println("Caldendar.setTime: " + (end - start) + " ms"); 
    } 
} 

Ergebnisse:

Clone: 13 ms 
Caldendar.setTime: 317 ms 

PS Ich bin nicht sicher, wenn Sie wirklich ein Calendar benötigen, oder eine Date, so fühlen sich frei zu Ändern Sie den Test ...

(In Reaktion auf die Kommentar: Testgenauigkeit zu verbessern, können Sie auch einzeln die Tests ausgeführt werden können, erhöhen Sie den Wert von N, ...)

+0

Ihr Test ist fehlerhaft, da die zweite Schleife davon profitiert, dass der Cache geladen und von der ersten Schleife aufgewärmt wird . Sie müssen jeden Testfall separat ausführen. –

+1

@Steve: Es ist einfach, das zu tun: Einfach den auskommentieren, den du nicht laufen möchtest ... Für mich ändert es nicht die Resultate. Eigentlich ist es sowieso irrelevant, da der * zweite * langsamer ist ... (BTW, ich wollte nur eine einfache, schnelle und dreckige Art präsentieren, dies in einem sehr kurzen Format zu testen) –

+0

Konnte das nicht behoben werden Der zweite Test verwendet ein anderes Date-Objekt, z. G. 'final Datum date_ = new Date();' und entsprechende 'cal.setTime (Datum _);'? – mike

1

ich nicht-by-reference passieren kann

Bist du sicher nicht. So etwas gibt es in Java nicht. Aber ich würde die Anforderung überprüfen. Was ist das tatsächliche Risiko, dass jemand das Datum ändern wird, wenn Sie die gleiche die ganze Zeit weitergeben? und kannst du das kontrollieren? z.B. indem getTime() vor und nach jedem Aufruf geprüft wird und eine RTE geworfen wird, wenn sich diese ändert?

+2

Dies ist defensive Codierung ... aufgrund der Art des Geschäfts, in dem wir uns befinden, könnte die zufällige Änderung des Datums eine große Klage sein ... –

1

In Scala würde ich einen clone() und eine Besetzung tun mit .asInstanceOf [Kalender] wie zum Kalender:

val now = Calendar.getInstance() 
val newDate = now.clone().asInstanceOf[Calendar] 
Verwandte Themen