Pregunta

Me acabo de escribir toda una propaganda sobre cómo llegué a este punto, pero pensé que es más fácil para publicar el código y dejar las cosas así:)

Por lo que yo puedo decir, el rendimiento de test3 () debe ser el mismo que test1 () - la única diferencia es donde se captura la excepción (en el interior del método de llamada para test1 (), dentro del método llamado de test3 ())

¿Por qué test3 () toman regularmente el tiempo en algún lugar entre test1 () y test2 () para completar?

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

}

Correr me da (JDK 1.6.0_13 en Windows XP) la salida:

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

Por lo tanto, las respuestas son bastante estrecha (estamos hablando de algo que es tan trivial que es irrelevante), btu tengo curiosidad!

Más tarde ...

Las personas han sugerido que hay optimización de JVM en el camino - Estoy de acuerdo. Por lo tanto, he roto cada prueba hacia abajo en su propio método de clase / principal y cada uno individualmente. Los resultados de este:

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

observaciones interesantes:

  • La brecha entre la captura de cada llamada en comparación con la captura de todo lo que fuera del bucle se reduce en su propia JVM (supongo que la optimización no va el cerdo entero en el caso de todas las pruebas en uno debido a las otras iteraciones que han sido realizado)
  • La brecha entre el try / catch de mi lado frente al try / catch dentro URLEncoder.encode () es ahora mucho más pequeño (la mitad de un segundo a través de iteraciones 5000000), pero aún no consistentemente ...
¿Fue útil?

Solución

Si lo ejecuta en el orden informados:

  

realizadas 2500000 codificaciones tratando de   coger cada uno en 34208ms
  2500000 realizadas codificaciones tratando de atrapar todas   en 31708ms
Realizado 2500000 codificaciones   con un método en desuso en 30738ms

Invertir el orden:

  

Realizado 2500000 codificaciones con una   método obsoleto en 32598ms
realiza   2500000 codificaciones tratando de atrapar todas   en 31239ms
Realizado 2500000 codificaciones   tratando de captar cada uno en 31208ms

Por tanto, yo en realidad no creo que se está viendo lo que cree que está viendo (por cierto, no es test1 66% más lento que test3, que es lo que sus puntos de referencia sugieren)

Otros consejos

Si usted tiene su explicación, creo que:

3 es ligeramente más lento que 1 debido a la llamada al método adicional implicado.

2 es más rápido que cualquiera de los dos, ya que no se 'creó' y 'derribar' excepción la atención relacionada con el código de bytes en cada bucle. Puede abrir una grieta en el código de bytes para ver la diferencia con javap - ver http://www.theserverside.com/tt/articles/article.tss?l=GuideJavaBytecode

Si usted utiliza 2 o 1 depende de qué comportamiento que desee, ya que no son equivalentes. Yo elegiría 1 sobre 3, ya que está a continuación, no utiliza un método obsoleto, lo que es más importante que pequeños aumentos de velocidad -. Pero sucede 1 es más rápido de todos modos

Por favor, corríjanme, pero el test2 para el bucle se ejecuta sólo 1 paso, a causa de la excepción de lanzar y test1 llamó la excepción dentro del bucle y se ejecuta 2500000 veces.

Cuando se captura la excepción fuera del bucle, el bucle no se iniciará de nuevo. Imprimir "int i" para estar seguro de la cantidad de pasos hizo el bucle.

El tercero es el más lento, debido a que los delegados método de la llamada al método en desuso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top