Die Java-Enum.valueOf () - Effizienz, wenn Wert nicht vorhanden
Welche halten Sie für effizienter?
Den Einsatz von 'Wochentag' ist nur ein Beispiel:
public enum WeekDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
}
Schleife durch, und überprüfen Sie, Tag string first:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; //day 'should' always be a weekday
if (isValidWeekDay(day)) {
WeekDay weekDay = WeekDay.valueOf(day); //won't throw exception
...
} else {
throw new InvalidWeekDayException(day); //subclass of RuntimeException
}
}
private boolean isValidWeekDay(String day) {
for (WeekDay weekDay : WeekDay.values()) {
if(weekDay.toString().equals(day))
return true;
}
return false;
}
Oder da in 99,99% der Fälle, der Tag wird richtig sein:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; //day 'should' always be a weekday
try {
WeekDay weekDay = WeekDay.valueOf(day); //might throw exception
...
} catch (IllegalArgumentException e) {
throw new InvalidWeekDayException(day, e);
}
}
Update:
Zu klären, wird der input-string wird aus einer client-Anwendung, sondern als ein Benutzer. Also in anderen Worten, es wäre ein Fehler zu erhalten, die eine nicht-Arbeitstag in diesem Beispiel.
- Es klingt nach einer spaßigen Antwort, aber ich würde überlegen, die eine, die lief am schnellsten, wenn ich profiliert es die effizienteste sein.
- Der String kommt von etwas, das ein Benutzer eingibt, oder ist es immer von intern?
- Ich würde diese stattdessen zu verwenden, wenn Sie wirklich tun, eine enum-Tage der Woche : joda-time.sourceforge.net/field.html#dayOfWeek
- Dank NimChimpsky - jedoch, dies ist nur ein einfaches Beispiel. Meine tatsächlichen enum-Domäne ist spezifisch....
- Warum fangen die
IllegalArgumentException
überhaupt, ob es einen Fehler bei der Programmierung?IllegalArgumentException
ist genau das, was ich erwarten würde, wenn ich fragte eine utility-Methode zum analysieren von Daten mit illegalem, dass ich mich übergeben. - Dank Mark - geklärt, die eigentliche Logik in meinem code...
- die Schleife macht nichts, was nicht valueof
- gute Antwort, in dem Fall die zweite Methode, die exception zu fangen würde Profil besser, da in 99,99% der Fälle wird die Zeichenfolge gültig ist.
- die manuelle loop-und valueOf sind nicht gleichwertig. Daher meine Frage.
- wie unterscheiden Sie sich ? Sie werfen InvalidWeekDayException, wenn der input-string ist nicht ein Tag in der Woche, in Großbuchstaben, in beiden Fällen.
- man wirft eine Ausnahme, die anderen nicht. Ich denke, es ist eine Frage, ob das werfen/fangen/retrhrowing ist effizienter als testen/werfen...
- Kam hier wollen zu wissen die Effizienz von Enum.valueOf() für das nachschlagen von Werten, aber diese Frage ist mehr über die Kosten der valueOf() findet und abfangen von Ausnahmen. Ich habe aktualisiert die Titel zu reflektieren. Für alle Fragen, die Antworten auf die erstere Art von gefunden in stackoverflow.com/questions/7164906#7165270 und die stackoverflow.com/questions/24254250#24254758
- Was Bruchteil des Programms ist diese enum-lookup? Es ist schwer zu glauben, dass diese machen einen messbaren Unterschied für das gesamte Programm.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß, das ist eine alte post, aber ich glaube Folgendes Ergebnis wird noch interessant. Ich Laufe 10000000 tests zu finden, die ein element in
enum ENUM {FIRST, SECOND, THIRD, FOURTH, LAST}
mit dem JDK 1.8. Die Tabelle unten zeigt die erforderliche Zeit, indem Sie einfache Schleife undvalueOf()
.Fazit - ich würde nicht verwenden
valueOf()
wenn ich erwarte, dass die Werte nicht passende enum.Was ist die Leistung besorgt über den 2. Ansatz? Abfangen einer Ausnahme wie, die kostet fast nichts. Mithilfe von Ausnahmen für die normale Ablaufsteuerung ist in der Regel eine schlechte Idee, aus einer design-Perspektive, die Tage, wo dies war eine Gegenleistung, sind lange vorbei. In einem debugger, mit Ausnahmen, wie bedeutsam die Kontrolle der Operationen verlangsamt Dinge nach unten mit einem Faktor von ungefähr 10. Aber dies wird optimiert durch die JIT-und es gibt keine messbaren Auswirkungen in der Produktion.
Diese zahlen basieren auf Erfahrungen mit einer Bewertung habe ich das zxing Projekt, das verwendet Ausnahmen für alle Arten von flow control. Als ich es das erste mal sah, war ich entsetzt. Ich denke immer noch, es ist nicht das beste design, aber ich habe ziemlich viel testen und kann sagen mit ein bisschen Vertrauen, dass es hatte keine wirklichen Auswirkungen auf die performance. Und dies ist ein Algorithmus, der war mit Ausnahmen alle über den Ort für die Ablaufsteuerung. Ihre situation, wo die exception wird nur geworfen, in sehr außergewöhnlichen Umständen, ist kein Thema.
Edit: ich habe ein downvote oder zwei auf meine Antwort, und ich möchte sicherstellen, dass ich bin super klar, was ich damit sagen will: ich glaube nicht, dass es eine gute Idee, mit Ausnahmen für die normale Ablaufsteuerung. Nur weil die performance nicht ein gutes argument für die nicht-Verwendung Ausnahmen von dieser Weg bedeutet nicht, dass es nicht andere, völlig legitimen Gründen (wie Lesbarkeit, Testbarkeit, Erweiterbarkeit). Im Fall des OP, die Verwendung von eine Ausnahme ist absolut angesagt, und definitiv nicht dazu führen, jede Art von performance-Problem.
Als kommentierte, Sie haben zu Profil, um herauszufinden, für sicher. Auch in Ihrem eigenen parsing-Ansatz, können Sie machen Sie schneller durch Rücksendung der enum beim analysieren der Liste.
Es sei denn, dies ist ein zeitkritischer Stück einer Anwendung, würde nicht ich sorgen über es in jedem Fall und nehmen Sie einfach die meisten lesbar Ansatz. Ich denke, das wäre mit dem Wochentag.valueOf () - Methode.
Wenn Sie lieber nicht zu tun haben mit Ausnahmen, dann erstellen Sie eine Karte Ihrer Werte in enum-und effektiv das gleiche, wie valueOf() aus einer lookup liefert null, wenn es nicht gefunden wird.
Dies ist effektiv, was die valueOf () - Methode mache, außer es wirft IllegalArgumentException, wenn es nicht gefunden wird. Dieser Ansatz wird einfach null zurückgegeben, also nicht die Erzeugung der stacktrace.
Wenn Ihre Frage ist wirklich über die Effizienz der Suche zu 7 Position haben Sie bereits verschwendet zu viel Zeit damit. Selbst die schnellsten Suchalgorithmen Ertrag null oder negativ nutzen, bis N > 15 oder so, andere als die O(1).
Speichern Sie die gültigen Zeichenfolgen in einer
HashSet
und entscheiden, ob ein string eine gültige Tages-oder nicht, basierend aufFestgelegt.enthält(...)
.Dem set kann ein
static final Set
, und Sie können wickeln Sie Sie in eine unveränderliche, für eine gute Maßnahme:Die Schleife tut nichts, der Aufruf von valueof nicht, Sie haben die gleiche Funktionalität : überprüfen Sie, ob Ihr string ist gültig, enum. Was tun Sie denken, Sie gewinnen ab der ersten option ?
Die zweite option die beste ist:
Oder Sie können eine lookup-enum-Werte in Ihrem enum, wenn die Klasse zum ersten mal geladen wird(siehe auch static-modifier) und validieren Sie mit get (), wie unten gezeigt:
Lassen Sie mich wissen, wenn Sie brauchen mehr details