Qui envisageriez-vous plus efficace?
L'utilisation de "la semaine" n'est qu'un exemple: p> boucle et vérifiez la chaîne de jour: P > 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);
}
}
7 Réponses :
stocker les chaînes valides dans un L'ensemble peut être un jeu final hashset code> et décidez si une chaîne est une journée valide ou non basée sur
set.Contains (...) code>
". statique code>, et vous pouvez envelopper une valeur non modifiable pour une bonne mesure: P>
private static final Map<String> WEEKDAY_STRINGS;
static {
HashSet<String> set = new HashSet();
for (WeekDay d : WeekDay.values()) {
set.add(d.toString());
}
WEEKDAY_STRINGS = Collections.unmodifiableSet(set);
}
Ceci est surchargé le problème IMHO
La boucle ne fait rien que l'appelant la valeurOf ne le fait pas, ils ont la même fonctionnalité: vérifier si votre chaîne est valide enum. Que pensez-vous que vous gagnez de la première option?
La deuxième option est la meilleure: p>
Je suppose que tout est à quel point les jours non valides sont communs. Si 50% des jours étaient invalides, certains considéreraient cela très inefficace de jeter / attraper une exception. Toutefois, si seul le bogue de l'application client rare, cela est définitivement la voie à suivre.
ou vous pouvez créer une recherche de valeurs ENUM à l'intérieur de votre Enum lorsque la classe première charge (voir modificateur statique) et validez à l'aide de GET () comme indiqué ci-dessous: Permettez-moi de savoir si Vous avez besoin de plus de détails p> p>
Comme a été commenté, vous devrez profiler pour savoir à coup sûr. Même dans votre propre approche d'analyse, vous pouvez le rendre plus rapide en retournant l'énumé lorsque vous analysez la liste.
public enum WeekDay { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY; private static Map<String, WeekDay> valueMap; public static WeekDay getValue(String possibleName) { if (valueMap == null) { valueMap = new HashMap<String, WeekDay>(); for(WeedDay day: values()) valueMap.put(day.toString(), day); } return valueMap.get(possibleName); } }
Quel est le problème de performance de la 2e approche? Attraper une exception comme ça coûte presque rien. L'utilisation d'exceptions pour le flux de contrôle normal est généralement une mauvaise idée d'une perspective de conception, les jours où cela a été une considération de performance. Dans un débogueur, en utilisant des exceptions comme des opérations de contrôle importantes ralentira les choses d'environ 10. Mais cela est optimisé par le JIT et il n'y a pas d'impact mesurable dans la production. P>
Ces chiffres sont basés sur l'expérience avec une évaluation que j'ai faite du projet ZXing, qui utilise des exceptions pour toutes sortes de contrôle de flux. Quand je l'ai vu pour la première fois, j'étais horrifié. Je pense toujours que ce n'est pas le meilleur design, mais j'ai fait de nombreux tests et je peux dire avec un bon peu de confiance qu'il n'avait aucun impact réel sur la performance. Et ceci est un algorithme qui utilisait des exceptions partout au lieu de contrôle de flux. Votre situation, où l'exception ne sera levée que dans des circonstances extrêmement exceptionnelles, n'est pas un problème. P>
Edit: J'ai eu un bowvote ou deux sur ma réponse, et je veux m'assurer que je suis très clair sur ce que je dis: je ne pense pas que c'est une bonne idée d'utiliser des exceptions pour la normale flux de contrôle. Ce n'est pas parce que la performance n'est pas un bon argument pour ne pas utiliser d'exceptions de cette façon ne signifie pas qu'il n'y a pas d'autres raisons parfaitement valables (telles que la lisibilité, la qualification, l'extension). Dans le cas de l'OP, l'utilisation d'une exception est absolument appelée et ne causerait certainement aucune sorte de problème de performance. P>
Si votre question concerne vraiment l'efficacité de la recherche de 7 articles, vous avez déjà trop gaspillé de temps dessus. Même les algorithmes de recherche les plus rapides donnent des avantages zéro ou négatif jusqu'à n> environ 15 ou plus que le O (1). P>
Je connais son ancien poste, mais je crois que le résultat après le résultat sera toujours intéressant. I Exécutez 10000000 tests pour trouver un élément dans conclusion - je n'utiliserais pas Enum Enum {premier, deuxième, troisième, quatrième, dernier} code> à l'aide de JDK 1.8. Le tableau ci-dessous montre l'heure requise par une boucle simple et une valeur
de () code>.
valueof () code> si Je m'attends à ce que les valeurs ne correspondent pas à Enum. P> p>
Votre test a-t-il été concentré sur le succès de l'efficacité de l'utilisation de l'exception alors? Ou la différence B / C était-elle de certains détails de mise en œuvre dans la méthode de la ValueOf ()? Avez-vous exécuté cela dans un JVM normalement exécuté (c'est-à-dire pas en mode de débogage) avec JIT activé? Et avez-vous réchauffé le Jit en commençant par une bande d'itérations avant de commencer vos minuteries? Lorsque j'ai fait mes tests avec ZXing, j'ai vu le type de différence que vous montrez lorsque j'ai couru des tests en mode de débogage - mais une fois que le débogueur était à l'écart, la performance était à peu près identique.
Hey @kevin. Il existe de nombreux paramètres qui peuvent affecter des figures concrètes dans la table. J'étais juste curieux de "coût d'exception" dans mon environnement i> (oracle JVM 1.6 + 64 bits Win7 + Débogou). J'étais tellement surpris par le résultat que j'ai décidé de le publier. Je m'attendais au ratio 10-20% dans le pire des cas sur la base de mon expérience C ++.
Cela peut sembler une réponse facétieuse, mais j'envisagerais celui qui a couru le plus rapide lorsque je lui ai profilé pour être le plus efficace.
La chaîne provenait-elle de quelque chose qu'un utilisateur entre dans ou est-ce que tout ira de l'interne?
J'utiliserais cela à la place, si vous faites vraiment une énumération de jours de la semaine: Joda -Time.sourceforge.net/field.html#dayofeek
Merci Nimchimpsky - Cependant, ce n'est qu'un exemple simple. Mon enum réel est un domaine spécifique ....
Pourquoi attraper le
illegalargumentException code> du tout, s'il s'agit d'une erreur de programmation?
IllegalArgumentException code> est exactement ce à quoi je m'attendrais si j'ai posé une méthode d'utilité pour analyser les données illégales que j'ai adoptées.
Merci Mark - clarifié la logique réelle utilisée dans mon code ...
La boucle ne fait rien de ce que la valeur ne fonctionne pas
@Oli - Bonne réponse, auquel cas la deuxième méthode d'attrape de l'exception donnerait mieux, car dans 99,99% des cas, la chaîne sera valide.
@Nimchimpsky La boucle manuelle et la valeurOf ne sont pas équivalentes. D'où ma question.
comment sont-ils différents ? Vous lancez InvalidWeekdayException lorsque la chaîne d'entrée n'est pas un jour de la semaine en majuscule, dans les deux cas.
@Nimchimpsky - on jette une exception, l'autre ne le fait pas. Je suppose que c'est une question de savoir si la lancée / attraper / rétrograder est plus efficace que celle des tests / jets ...
Est venu ici vouloir connaître l'efficacité de l'énum.valueof () pour rechercher des valeurs, mais cette question concerne davantage le coût de la valeur des valeurs () manquantes et attraper des exceptions. J'ai mis à jour le titre à refléter. Pour quiconque se demander, la réponse à l'ancien est un peu trouvée dans Stackoverflow.com/questions/7164906#7165270 et Stackoverflow.com/questions/24254250#24254758
Quelle fraction du programme est cette recherche enum? Il est difficile de croire que cela rendra une différence mesurable à l'ensemble du programme.