Schnellste Methode zum Parsen eines JJJJMMTT-Datums in Java [closed]

Beim Parsen eines JJJJMMTT-Datums, z. 20120405 für 5. April 2012, was ist die schnellste Methode?

<code>int year = Integer.parseInt(dateString.substring(0, 4));
int month = Integer.parseInt(dateString.substring(4, 6));
int day = Integer.parseInt(dateString.substring(6));
</code>

gegen

<code>int date = Integer.parseInt(dateString)
year = date / 10000;
month = (date % 10000) / 100; 
day = date % 100;
</code>

mod 10000 für Monat wäre, weil mod 10000 MMdd ergibt und das Ergebnis / 100 MM ist

Im ersten Beispiel führen wir 3 String-Operationen und 3 "parse to int" aus, im zweiten Beispiel führen wir viele Dinge über Modulo aus.

Was ist schneller? Gibt es eine noch schnellere Methode?

 user300104. Apr. 2012, 17:36
PS Ich war nur neugierig :) Danke für alle Antworten
 maerics04. Apr. 2012, 17:14
Warum konnten Sie keinen eigenen Mikro-Benchmark schreiben und sehen, welcher schneller ist?
 Dilum Ranatunga04. Apr. 2012, 17:13
Ich würde mir vorstellen, dass die Modulo-Mathematik viel schneller ist, als die drei (Unter-) Strings zuzuweisen ...
 user39576004. Apr. 2012, 17:16
@ DilumRanatunga Ich glaube, es gibt Möglichkeiten, eine Teilzeichenfolge zu verwenden, die das zugrunde liegende Array gemeinsam nutzt. Viele Sprachen tun dies nicht (zumindest nicht standardmäßig), da dies zu Undichtigkeiten führen kann, aber es ist perfekt für solche Anwendungsfälle.
 Joey04. Apr. 2012, 17:31
Dillum, das Erstellen eines Teilstrings in Java ist O (1) (zumindest in Suns Implementierung) und erfordert kein Kopieren. Dies ist jedoch mit einem tatsächlichen Datumsparser besser möglich. In beiden Fällen ist der Code kein Leistungsproblem (zumindest unwahrscheinlich).
 BalusC04. Apr. 2012, 17:22
Warum messen Sie es nicht einfach selbst?

Antworten auf die Frage(6)

Lösung für das Problem

ist die Leistung der Datumsverarbeitung nur für Sie relevantMillionen von Iterationen. Stattdessen sollten Sie eine Lösung wählen, die einfach zu lesen und zu warten ist.

Obwohl du es gebrauchen könntestSimpleDateFormatist es nicht wiedereintrittsfähig ("reentrant"), sollte also vermieden werden. Die beste Lösung ist die Verwendung der großartigen Joda-Zeitklassen:

<code>private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder()
     .appendYear(4,4).appendMonthOfYear(2).appendDayOfMonth(2).toFormatter();
...
Date date = DATE_FORMATTER.parseDateTime(dateOfBirth).toDate();
</code>

Wenn wir über Ihre mathematischen Funktionen sprechen, ist das erste, was Sie darauf hinweisen müssen, dass es Fehler in Ihrem Mathe-Code gab, die ich behoben habe.Das ist das problem mit der handarbeit. Diejenigen, die die Zeichenfolge einmal verarbeiten, sind jedoch die schnellsten. Ein kurzer Testlauf zeigt, dass:

<code>year = Integer.parseInt(dateString.substring(0, 4));
month = Integer.parseInt(dateString.substring(4, 6));
day = Integer.parseInt(dateString.substring(6));
</code>

Dauert ~ 800ms während:

<code>int date = Integer.parseInt(dateString);
year = date / 10000;
month = (date % 10000) / 100; 
day = date % 100;
total += year + month + day;
</code>

Dauert ~ 400ms.

Aber ... wieder ... Sie müssen berücksichtigen, dass dies danach ist10 Millionen Iterationen. Dies ist ein perfektes Beispiel für eine vorzeitige Optimierung. Ich würde diejenige wählen, die am besten lesbar und am einfachsten zu warten ist. Deshalb ist die Antwort von Joda die beste.

 Stephen C04. Apr. 2012, 17:38
+1 - um auf die Mängel im Ansatz des OP hinzuweisen. Ich hoffe nur, dass das OP versteht ...
 user300111. Okt. 2016, 13:00
Ich weiß, das ist alt, aber ich habe die Frage korrigiert, um Verwirrung zu vermeiden.
 user300104. Apr. 2012, 23:48
Ich verstehe :)
<code>SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
Date date = format.parse("20120405");
</code>
 Gray09. Okt. 2016, 16:17
SimpleDateFormat ist auch nicht wiedereintrittsfähig ("reentrant"). Dies funktioniert also nicht, wenn es von mehreren Threads verwendet wird, es sei denn, Sie erstellen einThreadLocal<SimpleDateFormat>
 Java Drinker04. Apr. 2012, 17:19
Dies ist der richtige Weg. Das Parsen einer Datumszeichenfolge sollte eine Leistungsoptimierung erfordern, es sei denn, Sie haben festgestellt, dass Sie dies für jede Anforderung oder dergleichen mehr als 10 Millionen Mal in einer Schleife tun ... (In diesem Fall sollten Sie Fragen, warum).
 Louis Wasserman04. Apr. 2012, 17:15
+1 für den richtigen Weg, dies zu tun.
 Corv1nus04. Apr. 2012, 17:23
Dies ist ein klassisches Beispiel dafür, wie Sie Ihre Werkzeuge kennen.
 user300104. Apr. 2012, 17:30
Die Java-Datums-API ist häufig zu langsam.
 Corv1nus04. Apr. 2012, 17:51
@ user3001 Wann hast du es aus Neugier zu langsam gefunden? Es ist nicht die am besten gestaltete API (Understatement), aber ich habe sie jahrelang ohne Leistungsprobleme verwendet.
 ytoledano19. Mai 2015, 15:30
Dies ist ziemlich langsam und macht sich in Schleifen bemerkbar, die viel kleiner als 10 Millionen sind
 user300104. Apr. 2012, 23:45
Schauen Sie sich das GregorianCalendar-Durcheinander an. Ich habe meine eigene Date-Klasse geschrieben und sie ist über 300-mal schneller, wenn ich mich an die Zahlen erinnere :) Also versuche ich, auch den Rest der API zu meiden, da sie möglicherweise gleichermaßen schlechter abschneidet.

die Mod-Methode wird schneller sein. Durch Aufrufen der Funktion erstellen Sie Variablen- und Standortinstanzen auf dem Stapel und erstellen eine schwerere Lösung.

Mod ist ein normaler mathematischer Operator und wahrscheinlich sehr optimistisch.

Aber wie Hunter McMillen sagte "Sie sollten sich die Calendar Class API ansehen"

mod zu% und füge fehlende Semikolons hinzu und repariere den Divisor imyear Berechnung. Trotzdem fällt es mir schwer, mir die Anwendung vorzustellen, bei der es sich um einen Engpass handelt. Wie oft analysieren Sie?YYYYMMdd Daten in ihre Komponenten, ohne dass sie validiert werden müssen?

 Stephen C04. Apr. 2012, 17:37
+1 - um darauf hinzuweisen, dass das OP wahrscheinlich seine Zeit auf der Suche nach der schnellsten Lösung verschwendet.

bei dem beide Methoden jeweils 1 Million Mal ausgeführt wurden. Die Ergebnisse zeigen deutlich, dass die Modulo-Methode viel schneller ist, wie Dilum Ranatunga vorausgesagt hat.

<code>t.startTiming();
for(int i=0;i<1000000;i++) {
    int year = Integer.parseInt(dateString.substring(0, 4));
    int month = Integer.parseInt(dateString.substring(4, 6));
    int day = Integer.parseInt(dateString.substring(6));
}
t.stopTiming();
System.out.println("First method: "+t.getElapsedTime());

Time t2 = new Time();
t2.startTiming();
for(int i=0;i<1000000;i++) {
    int date = Integer.parseInt(dateString);
    int y2 = date / 1000;
    int m2 = (date % 1000) / 100;
    int d2 = date % 10000;
}
t2.stopTiming();
System.out.println("Second method: "+t2.getElapsedTime());
</code>

Die Ergebnisse lügen nicht (in ms).

<code>First method: 129
Second method: 53
</code>

ohne etwas zu sagen ...):

<code>public static void main(String[] args) throws Exception {
    char zero = '0';
    int yearZero = zero * 1111;
    int monthAndDayZero = zero * 11;
    String s = "20120405";
    int year = s.charAt(0) * 1000 + s.charAt(1) * 100 + s.charAt(2) * 10 + s.charAt(3) - yearZero;
    int month = s.charAt(4) * 10 + s.charAt(5) - monthAndDayZero;
    int day = s.charAt(6) * 10 + s.charAt(7) - monthAndDayZero;
}
</code>

Wenn ich einen schnellen und schmutzigen Benchmark mit 100.000 Aufwärm-Iterationen und 10.000.000 zeitgesteuerten Iterationen durchführe, erhalte ich:

700ms für Ihre erste Methode350ms für Ihre zweite Methode10ms mit meiner Methode.
 assylias04. Apr. 2012, 18:38
@Alderath Stimme vollkommen zu - ich würde niemals das, was ich gepostet habe, in meinen Code aufnehmen! Aber es beantwortet die Frage!
 Nim04. Apr. 2012, 17:37
Ignoriere meinen Kommentar, ich habe die Anpassung nicht gesehenyearZero usw..
 assylias04. Apr. 2012, 17:20
@nim nicht sicher, was du meinst - Jahr ist 2012 nach der Berechnung.
 Alderath04. Apr. 2012, 18:17
In fast allen normalen Situationen würde ich die Modulo-Lösung vom OP bevorzugen, auch wenn dies schneller ist. Warum? Weil Sie in wenigen Sekunden verstehen, was passiert, wenn Sie diesen Code sehen. Ihr Code ist ein bisschen schlauer, benötigt aber auch mehr Zeit zum Verstehen, was ein Nachteil ist. Und ich bezweifle, dass es viele Situationen gibt, in denen die Datumskonvertierung der Leistungsengpass ist.

Ihre Antwort auf die Frage