Frage

Ich schrieb einen ganzen Klappentext, wie ich diesen Punkt erreicht, aber dachte, es ist einfacher, den Code zu schreiben und es dabei zu belassen:)

Soweit ich das beurteilen kann, sollte die Leistung von test3 () das gleiche sein wie test1 () - der einzige Unterschied ist, wo die Ausnahme (im Rufmethode für test1 () gefangen wird, innerhalb der aufgerufenen Methode für test3 ())

Warum test3 () regelmäßig Zeit irgendwo zwischen test1 () und test2 () in Anspruch nehmen,?

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

}

Beim Laufen gibt mir (JDK 1.6.0_13 unter Windows XP) die Ausgabe:

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

So sind Antworten ziemlich nahe (wir sprechen etwas, das es ist irrelevant, so trivial ist), btu Ich bin gespannt!

Später ...

Die Menschen haben vorgeschlagen, dass es JVM-Optimierung ist in die Quere - Ich bin damit einverstanden. So habe ich jeden Test gliedert sich in seine eigene Klasse / main-Methode und jedes einzeln. Die Ergebnisse aus dieser:

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

Interessante Beobachtungen:

  • Die Lücke zwischen jedem Anruf fängt gegen alles, was außerhalb der Schleife zu kontrollieren ist in einem eigenen JVM reduziert (ich nehme an Optimierung ist das ganze Schwein im All-Tests-in-one Fall aufgrund der anderen Iterationen nicht gehen, die gewesen sind durchgeführt wird)
  • Die Lücke zwischen dem try / catch auf meiner Seite gegen die try / catch innerhalb URLEncoder.encode () ist jetzt viel kleiner (eine halbe Sekunde über 5.000.000 Iterationen), aber immer noch da consistantly ...
War es hilfreich?

Lösung

Beim Laufen sie in der gewünschten Reihenfolge geschrieben:

  

Ausgeführte 2500000 Codierungen versuchen,   fangen jeweils in 34208ms
  Performed 2500000 Codierungen versuchen, alle zu fangen   in 31708ms
Performed 2500000 Codierungen   mit einer veralteten Methode in 30738ms

Die Umkehrung der Reihenfolge:

  

Ausgeführte 2500000 Kodierungen mit einem   veraltet Methode in 32598ms
Performed   2500000 Codierungen versuchen, alle zu fangen   in 31239ms
Performed 2500000 Codierungen   versuchen, jeden in 31208ms zu fangen

Darum soll sie eigentlich glaube ich nicht, dass du sehen, was Sie denken, Sie sehen (natürlich, test1 66% langsamer als test3 ist, das ist, was Ihr Benchmarks vorschlagen)

Andere Tipps

Ja, Sie haben Ihre Erklärung, denke ich:

3 ist etwas langsamer als 1 aufgrund des zusätzlichen Methodenaufruf beteiligt.

2 ist schneller als entweder da es einrichten "nicht und‚abzureißen‘Ausnahme fallbezogene Bytecode in jeder Schleife. Sie können den Byte-Code knacken offen für die Differenz mit javap - siehe http://www.theserverside.com/tt/articles/article.tss?l=GuideJavaBytecode

Ob Sie 2 oder 1 hängt davon ab, welches Verhalten Sie wollen, da sie nicht gleichwertig sind. Ich würde 1 über 3 wählen, da Sie dann nicht eine veraltete Methode, die wichtiger ist als winzige Geschwindigkeit erhöht ist -. Aber wie es geschieht 1 ist schneller sowieso

Bitte korrigieren Sie mich, aber die test2 for-Schleife führt nur 1 Schritt, weil der Wurf Ausnahme und test1 die Ausnahme innerhalb der Schleife gefangen und wird 2.500.000-mal ausgeführt.

Wenn Sie die Ausnahme außerhalb der Schleife zu fangen, wird die Schleife nicht wieder von vorn anfangen. Drucken Sie „int i“ um sicher zu sein, wie viele Schritte die Schleife gemacht.

Die dritte ist die langsamste, da die Methode Delegierten der Aufruf an die veraltete Methode.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top