10
votes

Java Enum.Valueof () Efficacité lorsque la valeur n'existe pas

Qui envisageriez-vous plus efficace?

L'utilisation de "la semaine" n'est qu'un exemple: p> xxx pré>

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);
    }
}


13 commentaires

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 du tout, s'il s'agit d'une erreur de programmation? IllegalArgumentException 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.


7 Réponses :


2
votes

stocker les chaînes valides dans un hashset code> et décidez si une chaîne est une journée valide ou non basée sur set.Contains (...) code> ".

L'ensemble peut être un jeu final 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);
}


1 commentaires

Ceci est surchargé le problème IMHO



2
votes

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: xxx


1 commentaires

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.



2
votes

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: XXX

Permettez-moi de savoir si Vous avez besoin de plus de détails


0 commentaires

8
votes

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);

    }
 }


0 commentaires

8
votes

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.

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.

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.


0 commentaires

3
votes

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).


0 commentaires

7
votes

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 Enum Enum {premier, deuxième, troisième, quatrième, dernier} à l'aide de JDK 1.8. Le tableau ci-dessous montre l'heure requise par une boucle simple et une valeur de () . xxx

conclusion - je n'utiliserais pas valueof () si Je m'attends à ce que les valeurs ne correspondent pas à Enum.


2 commentaires

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 (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 ++.