Question

Je viens d'écrire un texte de présentation tout sur la façon dont je suis arrivé à ce point, mais pensé qu'il est plus facile d'afficher le code et le laisser à ce:)

Pour autant que je peux dire, la performance de test3 () devrait être le même que test1 () - la seule différence est l'endroit où l'exception est pris (dans la méthode d'appel pour test1 (), l'intérieur de la méthode appelée pour test3 ())

Pourquoi test3 () prend régulièrement du temps quelque part entre test1 () et test2 () pour terminer?

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class Test {

    public static void main(String[] args) {
        warmup(); 
        test1(2500000); // Exception caught inside the loop
        test2(2500000); // Exception caught outside the loop
        test3(2500000); // Exception caught "inside" the loop, but in the URLEncoder.encode() method
    }

    private static void warmup() {
        // Let URLEncoder do whatever startup it needs before we hit it
        String encoding = System.getProperty("file.encoding");
        try {
            URLEncoder.encode("ignore", encoding);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private static void test1(int count) {
        String encoding = System.getProperty("file.encoding");
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            try {
                URLEncoder.encode("test 1 " + i, encoding);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings trying to catch each in " + (end - start) + "ms");
    }

    private static void test2(int count) {
        String encoding = System.getProperty("file.encoding");
        long start = System.currentTimeMillis();
        try {
            for (int i = 0; i < count; i++) {
                URLEncoder.encode("test 2" + i, encoding);
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings trying to catch all in " + (end - start) + "ms");
    }

    private static void test3(int count) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            URLEncoder.encode("test 3 " + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Performed " + count + " encodings with a deprecated method in " + (end - start) + "ms");
    }

}

Running il me donne (JDK 1.6.0_13 sous Windows XP) la sortie:

Performed 2500000 encodings trying to catch each in 4906ms
Performed 2500000 encodings trying to catch all in 2454ms
Performed 2500000 encodings with a deprecated method in 2953ms

Alors, les réponses sont assez proches (on parle quelque chose qui est si trivial qu'il est hors de propos), btu Je suis curieux!

Plus tard ...

Les gens ont suggéré qu'il ya optimisation JVM obtenir de la manière - je suis d'accord. Donc, je me suis cassé chaque test embarqua sa propre méthode de classe / main et chacun individuellement. Les résultats de ceci:

1 - Performed 2500000 encodings trying to catch each in 5016ms
1 - Performed 5000000 encodings trying to catch each in 7547ms
1 - Performed 5000000 encodings trying to catch each in 7515ms
1 - Performed 5000000 encodings trying to catch each in 7531ms

2 - Performed 2500000 encodings trying to catch all in 4719ms
2 - Performed 5000000 encodings trying to catch all in 7250ms
2 - Performed 5000000 encodings trying to catch all in 7203ms
2 - Performed 5000000 encodings trying to catch all in 7250ms

3 - Performed 2500000 encodings with a deprecated method in 5297ms
3 - Performed 5000000 encodings with a deprecated method in 8015ms
3 - Performed 5000000 encodings with a deprecated method in 8063ms
3 - Performed 5000000 encodings with a deprecated method in 8219ms

Des observations intéressantes:

  • L'écart entre la capture chaque appel contre la capture tout à l'extérieur de la boucle est réduite dans sa propre machine virtuelle Java (je suppose que l'optimisation ne va pas tout le porc en all-tests en un cas en raison des autres itérations qui ont été effectué)
  • L'écart entre les try / catch de mon côté par rapport à l'try / catch dans URLEncoder.encode () est maintenant beaucoup plus petite (une demi-seconde sur 5000000 itérations) mais toujours consistantly là ...
Était-ce utile?

La solution

L'exécution dans l'ordre que vous avez affichée:

  

Interprétée 2500000 encodages essayant de   attraper chacun dans 34208ms
  2500000 encodages effectués en essayant d'attraper tous   en 31708ms
Joué 2500000 encodages   avec un procédé obsolète dans 30738ms

Inverser l'ordre:

  

Joué 2500000 encodages avec   méthode désapprouvée dans 32598ms
Effectué   2500000 encodages essayant d'attraper tous   en 31239ms
Joué 2500000 encodages   en essayant d'attraper chacun dans 31208ms

Je ne pense donc pas vraiment vous voyez ce que vous pensez que vous voyez (certainement, test1 est pas 66% plus lent que test3, qui est ce que vos repères suggèrent)

Autres conseils

Oui, vous avez votre explication, je pense:

3 est légèrement inférieure à 1 en raison de l'appel de méthode supplémentaire impliqué.

2 est plus rapide que ce soit, car il ne « mis en place » et « démolir » bytecode exception liée accrocheur dans chaque boucle. Vous pouvez entrouvrir le code octet pour voir la différence avec javap - voir http://www.theserverside.com/tt/articles/article.tss?l=GuideJavaBytecode

Si vous utilisez 2 ou 1 dépend de quel comportement que vous voulez, car ils ne sont pas équivalents. Je choisirais 1 sur 3 puisque vous êtes alors n'utilisez une méthode dépréciée, ce qui est plus important que la vitesse augmente minuscules -. Mais comme il arrive 1 est plus rapide de toute façon

S'il vous plaît me corriger, mais le test2 boucle for exécute seulement 1 étape, en raison de l'exception et de lancer test1 pris l'exception dans la boucle et est exécuté 2500000 fois.

Lorsque vous attrapez l'exception en dehors de la boucle, la boucle ne redémarrera pas. Imprimez « int i » pour être sûr combien de pas la boucle faite.

Le troisième est le plus lent, du fait que les participants de la méthode de l'appel à la méthode obsolète.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top