¿ La creación de un objeto a través de la reflexión, en lugar de llamar al constructor de la clase resultado significativas las diferencias en el rendimiento?

InformationsquelleAutor dmanxiii | 2009-01-12

14 Comentarios

  1. 162

    Sí – absolutamente. Buscando una clase a través de la reflexión es, por su magnitud, más caro.

    Citando Java la documentación de reflexión:

    Debido a que la reflexión implica tipos que son dinámicamente resuelto, ciertos máquina virtual de Java optimizaciones no pueden ser realizadas. En consecuencia, reflexivo operaciones tienen un rendimiento más lento que su no-reflectante contrapartes, y deben evitarse en las secciones de código que se llama con frecuencia en el rendimiento de las aplicaciones sensibles.

    He aquí una prueba sencilla que he cortado en 5 minutos en mi máquina, la ejecución de Sun JRE 6u10:

    public class Main {
    
        public static void main(String[] args) throws Exception
        {
            doRegular();
            doReflection();
        }
    
        public static void doRegular() throws Exception
        {
            long start = System.currentTimeMillis();
            for (int i=0; i<1000000; i++)
            {
                A a = new A();
                a.doSomeThing();
            }
            System.out.println(System.currentTimeMillis() - start);
        }
    
        public static void doReflection() throws Exception
        {
            long start = System.currentTimeMillis();
            for (int i=0; i<1000000; i++)
            {
                A a = (A) Class.forName("misc.A").newInstance();
                a.doSomeThing();
            }
            System.out.println(System.currentTimeMillis() - start);
        }
    }

    Con estos resultados:

    35 //no reflection
    465 //using reflection

    Tener en cuenta la búsqueda y la creación de instancias, se realiza en conjunto, y en algunos casos, la búsqueda puede ser refactorizado de distancia, pero esto es sólo un ejemplo básico.

    Incluso si usted acaba de crear una instancia, usted todavía obtener un impacto en el rendimiento:

    30 //no reflection
    47 //reflection using one lookup, only instantiating

    De nuevo, YMMV.

    • En mi máquina .newInstance() la llamada con sólo una Clase.forName() la llamada de las puntuaciones de 30 o así. Dependiendo de VM versión, la diferencia puede estar más cerca de lo que piensas, con una adecuada estrategia de almacenamiento en caché.
    • En mi sistema (un dual core 2.4 GHz), veo los tiempos de Instancias: 7.8, Reflejar 1: 171.9, y Reflejar las 2: 3181.3 (donde reflejar la 2 es la reflexión como en el anterior, y 1 es la reflexión con forName hecho solamente una vez – todos los tiempos son de 1.000.000 de iteraciones).
    • También, este factor de rendimiento depende mucho del costo de la inicialización del objeto – es decir, el trabajo que se hace en el constructor.
    • Amigo, gracias por el trabajo con los números en este. Veo reflexión utilizado en el código del lado del servidor, y me da los pelos de punta. 😉
    • En general, usted usaría para crear una instancia de un objeto una vez y se mantiene en la instancia. No sería una buena idea para algo que se puede hacer 100 veces o más de un segundo, pero luego, cuando usted está haciendo algo más que 100x un segundo que se debe prestar atención a ella. Una vez que se ha instanciado el objeto, su uso no es peor (a menos que usted está accediendo a los métodos a través de la reflexión así). Me alegro que la reflexión es lo suficientemente duro como para asustar a muchas personas. Ruby es muy fácil… lo hace muy utilizado en gran medida-y me pone un poco nervioso.
    • Lawrey a continuación señaló que esta prueba era completamente inválida porque el compilador de optimización de la no-reflectante solución (Que incluso puede ser que no se hace nada y optimizar el bucle for). Necesita ser re-trabajado y probablemente debería ser eliminado de S. O. como malo / información engañosa. Caché de los objetos creados en una matriz en ambos casos para evitar que el optimizador de optimización de fuera. (No puede hacer esto en la reflexión de la situación porque no puede demostrar que el constructor no tiene efectos secundarios)
    • K – no te dejes llevar. Sí, los números son debido a las optimizaciones. No, la prueba es no completamente inválida. He añadido una llamada que elimina cualquier posibilidad de sesgar el resultado, y los números siguen apilados contra la reflexión. En cualquier caso, recuerde que este es un muy crudo micro-punto de referencia que demuestra que la reflexión siempre incurre en una cierta sobrecarga
    • Por supuesto, supone una sobrecarga que alguien debe ser consciente de si hacer nada dentro de un bucle de un millón de iteraciones o más, por supuesto, en ese punto, usted debe tomar en la consideración de los males de la creación de instancias de objeto y de la cadena de contatenation así-y ninguno de estos debe ser considerada hasta que estamos haciendo dentro de un bucle de un millón o más (y, probablemente, ni siquiera entonces!)
    • Esta es, probablemente, un inútil de referencia. Dependiendo de lo que haceralgo hace. Si no hace nada con cara visible efecto, su punto de referencia sólo se ejecuta código muerto.
    • Punto de referencia es no tomar en consideración la JVM de calentamiento / fase de compilación. Envuelva principal del contenido en un bucle, y podrás ver completamente diferentes números en posteriores ejecuciones.
    • He sido testigo de la JVM de la optimización de la reflexión de 35 veces. Ejecución de la prueba repetidamente en un bucle es la forma de probar el código optimizado. Primera iteración: 3045ms, segunda iteración: 2941ms, tercera iteración: 90ms, cuarta iteración: 83ms. Código: c.newInstance(i). c es un Constructor. No reflectante código: new a(i), el cual arroja 13, 4, 3.. ms veces. Así que sí, la reflexión en este caso fue lento, pero no tan mucho más lento que lo que la gente está concluyendo, porque cada una de las pruebas que estoy viendo, son simplemente ejecutar la prueba de una vez, sin dar la JVM la oportunidad para reemplazar los códigos de byte con el código máquina.
    • según sus números, la Reflexión es aún peor de lo que sale en Yuvals prueba – en lugar de un factor de 13x más lento, sus números iniciales son 234x más lento, y en lugar de 1.6 x más lento para la optimización, los números indican que la reflexión es 27x(!) más lento. En otras palabras, de acuerdo a sus números, no solo la de «casi como mucho más lento de lo que la gente está concluyendo», es MUCHO más lento de lo que la gente está concluyendo.
    • lo que podría ser. Después de todo, la re-compilado «calentado» el código de los beneficios de la no-reflexión versión mucho más. Con la reflexión, se pasa la mayor parte de su tiempo dentro de las bibliotecas.
    • Tenga en cuenta que System.currentTimeMillis() no se utiliza para un punto de referencia como este debido a su común granularidad en el orden de 10-20ms! System.nanoTime() debe ser utilizado, o el bucle de la cuenta aumentó por un factor de 100 o más.
    • el uso de JMH para todos sus microbenchmarks, me sugieren para eliminar un punto de referencia código aquí porque es engañoso

  2. 83

    Sí, es más lento.

    Pero recuerda que la maldita regla #1–OPTIMIZACIÓN PREMATURA ES LA RAÍZ DE TODOS los males

    (Bueno, puede estar vinculada con el #1 de SECO)

    Juro, si a alguien se le ocurrió a mí en el trabajo y me preguntó que me gustaría estar muy atentos sobre su código para los próximos meses.

    Nunca se debe optimizar hasta que usted esté seguro de que la necesita, hasta entonces, sólo tiene que escribir bien, un código legible.

    Ah, y no me refiero a escribir estúpido código. Sólo estar pensando en la forma más limpia pueden hacerlo–no copiar y pegar, etc. (Todavía desconfía de cosas como bucles interiores y el uso de la colección que mejor se adapte a su necesidad–Ignorar estos no se «unoptimized» la programación, es el «malo» de la programación)

    Me asusta cuando me escuchan preguntas como esta, pero luego se me olvida que todo el mundo tiene que ir a través del aprendizaje de todas las reglas antes de que realmente lo consigue. Se obtendrá después de haber pasado un mes-hombre de depuración de algo a alguien «Optimizado».

    EDICIÓN:

    Sucedió algo interesante en este hilo. Compruebe el #1 de responder, es un ejemplo de lo poderoso que el compilador está en la optimización de las cosas. La prueba es completamente válido porque el no-reflexiva de la creación de instancias puede ser completamente factorizada fuera.

    Lección? No vuelvas a optimizar hasta que hayas escrito un limpio, perfectamente codificado solución y probado que esto es demasiado lento.

    • Estoy totalmente de acuerdo con el sentimiento de esta respuesta, sin embargo, si estás a punto de embarcarse en una importante decisión de diseño que ayuda a tener una idea sobre el rendimiento, por lo que no se van en un totalmente impracticable el camino. Tal vez haciendo la debida diligencia?
    • -1: Evitar hacer las cosas de la manera equivocada no es la optimización, es sólo hacer las cosas. La optimización está haciendo las cosas mal, complicada ya sea real o imaginaria de los problemas de rendimiento.
    • totalmente de acuerdo. La elección de una lista enlazada a través de una lista de matriz para una ordenación por inserción es simplemente la manera correcta de hacer las cosas. Pero esta pregunta en particular, hay un buen uso de los casos para ambos lados de la pregunta original, por lo que elegir uno basado en el desempeño, más que la más útil de la solución estaría mal. No estoy seguro de que estamos en desacuerdo en todo, así que no estoy seguro de por qué dijo «-1».
    • Porque no se debe mencionar el rendimiento como un problema en absoluto, hasta que se ha establecido como la cosa correcta de hacer. En este contexto, constructor de objetos en el interior de su tipo de comprobación/compilación de ‘el mundo’, la reflexión de las cosas fuera de ella. El rendimiento es como el precio, sólo porque algo es caro, no en sí mismo, lo hacen mejor. $10 de reloj digital, probablemente, le dice a la vez tan bien o mejor que un $30,000 platino pedazo de bling.
    • eso es exactamente lo que he dicho. Todavía no sé por qué usted se siente que estamos en desacuerdo. Hizo usted posiblemente malinterpretado mi post? «Nunca debes optimizar hasta que usted esté seguro de que la necesita» == «no hay que mencionar el rendimiento como un problema en absoluto, hasta que se ha establecido como la cosa correcta de hacer.»
    • Cualquier sensato analista programadores necesita considerar la eficiencia en una etapa temprana o usted podría terminar con un sistema que NO puede ser optimizada en forma eficiente y costworthy plazo. No, no optimizar cada ciclo de reloj, pero que la mayoría no duda de emplear las mejores prácticas para algo tan básico como la creación de instancias de clase. Este ejemplo es una de las grandes razones por considerar que ese tipo de preguntas con respecto a la reflexión. Sería una muy pobre programador que iban delante y utilizan la reflexión a lo largo de un millón de sistema de línea sólo para más tarde descubrir que era órdenes de magnitud demasiado lento.
    • Riley Generalmente creación de instancias de clase es un tipo bastante raro evento para la selección de clases va a utilizar la reflexión sobre los. Supongo que tienes razón, aunque-algunas personas pueden crear instancias de cada clase reflexiva, incluso a aquellos que se renuevan constantemente. Yo diría que bastante mala programación (aunque ya entonces se PODRÍA implementar una caché de instancias de la clase para su reutilización después de los hechos y no hacer daño a su código demasiado, así que supongo que todavía iba a decir SIEMPRE de diseño para mejorar la legibilidad, a continuación, perfil y optimizar más tarde)
    • -1: teniendo en cuenta la simplicidad y genericity de la pregunta, esta respuesta es solo ruido… aunque comparto sus sentimientos 🙂
    • Como con la pregunta «¿Cuál es la mejor manera de suicidarse» o «¿Cómo puedo hacer mejor objetivo de este arco para disparar la manzana de mi hermana en la cabeza», la respuesta directa, no resuelve el problema de fondo expuestos por la cuestión de la existencia y en todas las probabilidad desesperarte es, posiblemente resultando en que alguien salga herido!
    • Sí, evita la optimización, pero que no responde a la pregunta. Definitivamente, hay veces cuando la respuesta de los asuntos.
    • no «Sí, es más lento» respuesta a la pregunta? Me dio la respuesta todo el significado que yo pensaba que se lo merecía … me lo puso en la parte superior y la hizo breve con el fin de mejorar el verdadero punto de que si usted está pensando en la optimización de esta manera es casi seguro Que hace las cosas Mal, pero me contestó…
    • En desacuerdo parcialmente. Con frecuencia es necesario pensar en el rendimiento en tiempo de diseño, el mundo está lleno de descuento bloaty APIs de java/Estándares que funcionan mal porque de seguir esta regla. Algunas cosas no pueden ser optimizados que fácil en las etapas finales de un proyecto.
    • También, todos me sugirió que era el código del bien, de la unidad de la prueba de rendimiento y, a continuación, corregir si se realiza a continuación un conjunto de barras. Nunca me dijo que lo deje hasta el final del proyecto o ignorar por completo. El primer paso a través, de la codificación tan claramente como pueda, mejorar su optomized código y damos a conocer las buenas pruebas de unidad. Usted realmente tiene un problema con esto?
    • La cita completa es:»Nos debe olvidarse de los pequeños de la eficiencia, dicen que cerca del 97% del tiempo: optimización prematura es la raíz de todos los males. Sin embargo, no debemos dejar pasar las oportunidades que la crítica del 3%. Un buen programador no se deje llevar por la complacencia por este razonamiento, será sabio mirar cuidadosamente el código crítico; pero sólo después de que el código ha sido identificado» – Donald Knuth
    • Yo creo que es casi exactamente lo que yo estaba diciendo:–yo reformuló el resto, pero dejó fuera a ninguno de los sentament de la cita original.
    • muy a la derecha, a la preocupación acerca del rendimiento durante el tiempo de codificación tiene más problemas para luego resolver.

  3. 34

    Usted puede encontrar que a a = new a() está siendo optimizado por la JVM.
    Si usted pone los objetos en una matriz, que no se realizan tan bien. 😉
    El siguiente imprime…

    new A(), 141 ns
    A.class.newInstance(), 266 ns
    new A(), 103 ns
    A.class.newInstance(), 261 ns
    
    public class Run {
        private static final int RUNS = 3000000;
    
        public static class A {
        }
    
        public static void main(String[] args) throws Exception {
            doRegular();
            doReflection();
            doRegular();
            doReflection();
        }
    
        public static void doRegular() throws Exception {
            A[] as = new A[RUNS];
            long start = System.nanoTime();
            for (int i = 0; i < RUNS; i++) {
                as[i] = new A();
            }
            System.out.printf("new A(), %,d ns%n", (System.nanoTime() - start)/RUNS);
        }
    
        public static void doReflection() throws Exception {
            A[] as = new A[RUNS];
            long start = System.nanoTime();
            for (int i = 0; i < RUNS; i++) {
                as[i] = A.class.newInstance();
            }
            System.out.printf("A.class.newInstance(), %,d ns%n", (System.nanoTime() - start)/RUNS);
        }
    }

    Esta sugieren que la diferencia es de unos 150 ns en mi máquina.

    • tan sólo has matado el optimizador de conversiones, así que ahora ambas versiones son lentos. La reflexión es, por lo tanto, aún terriblemente lento.
    • si el optimizador de la optimización de la creación de sí mismo, entonces no era una prueba válida. @Pedro de prueba es por lo tanto válido, porque de hecho se compara la creación de veces (El optimizador de no ser capaz de trabajar en CUALQUIER situación real, ya que en cualquier situación real que necesita de los objetos que son instancias).
    • En el que caso de que usted podría haber aprovechado la oportunidad para crear un mejor punto de referencia. Tal vez usted puede ofrecer algo constructivo, como lo que debe ser en el cuerpo del método.
    • en mi mac, openjdk 7u4, la diferencia es 95ns frente a 100 ns. En lugar de almacenar en la matriz, me almacenar hashCodes. Si usted dice -verbose:clase se puede ver cuando hotspot genera bytecode para la construcción de Un y el acompañamiento de la aceleración.
    • Si he de búsqueda de una vez (una llamada aClass.getDeclaredMethod) y, a continuación, llamar a Method.invoke varias veces? Estoy utilizando la reflexión una vez o tantas veces como yo lo invoque? pregunta de Seguimiento, ¿y si en vez de Method es un Constructor y yo Constructor.newInstance varias veces?
    • usted está utilizando la reflexión tantas veces como quieras llamarlo. Como la JVM se calienta de esta manera se consigue más eficiente en el tiempo, pero la reflexión es todavía allí.
    • Entonces ¿por qué la diferencia de tiempo, en @Yuval ‘s respuesta anterior, en el caso de un lookup y de uso múltiple bastante menor que ~150ns? O se volvió a golpear a algún tipo de optimización (supongo que no)?
    • 150 ns suena como mucho tiempo. Una simple llamada al método toma alrededor de 50 ns y después de inline que no podría tomar algún tiempo en absoluto. Espero reflaction no es lento para los casos más sencillos, al menos.
    • Tiene sentido! Gracias!
    • para darle un poco de contexto, en el que estoy trabajando si una persistencia de la biblioteca que lleva 75 ns para leer/escribir un pequeño indexado mensaje. Usted puede hacer mucho en esa cantidad si el tiempo.
    • Sólo por diversión que ejecutar su «prueba» en un Android nexus 9. No me esperaba esto : new a(), 146 ns A. clase.newInstance(), 1 356 ns new a(), 187 ns A. clase.newInstance(), 1 374 ns
    • algunos aspectos del JIT en Android no son tan fuertemente optimizado.
    • Me he dado cuenta! Me preguntaba por qué mi app era un poco lento en la recuperación de datos… sé dónde buscar ahora 🙂
    • Inútil?… Qué irónico.

  4. 26

    Si no realmente se necesita algo más rápido que el de la reflexión, y no sólo una prematura de optimización, luego de código de bytes de generación con ASM o un nivel más alto de la biblioteca es una opción. Generar el código de bytes de la primera vez es más lento que sólo mediante la reflexión, pero una vez que el bytecode que se ha generado, es tan rápido como normal código de Java y será optimizado por el compilador JIT.

    Algunos ejemplos de aplicaciones que utilizan la generación de código:

    • Invocar a los métodos de proxy generado por CGLIB es ligeramente más rápido que Java proxies dinámicos, porque CGLIB genera bytecode para sus aliados, pero proxies dinámicos utilizar sólo la reflexión (He medido CGLIB a ser de alrededor de 10 veces más rápido que en las llamadas de método, pero la creación de proxies fue más lento).

    • JSerial genera bytecode para leer/escribir en los campos de los objetos serializados, en lugar de utilizar la reflexión. Hay algunos puntos de referencia en JSerial del sitio.

    • Yo no estoy 100% seguro (y no tengo ganas de leer la fuente ahora), pero creo que Guice genera bytecode para hacer la inyección de dependencia. Me corrija si estoy equivocado.

    • +1 para proporcionar una posible solución
  5. 24

    «Significativo» es totalmente dependiente de contexto.

    Si usted está usando la reflexión para crear un único objeto de controlador basado en algún archivo de configuración y, a continuación, pasar el resto de su tiempo de ejecución de consultas de base de datos, entonces es insignificante. Si usted está creando una gran cantidad de objetos a través de la reflexión en un bucle estrecho, entonces sí, es significativo.

    En general, flexibilidad de diseño (donde sea necesario!) que debe impulsar el uso de la reflexión, no el rendimiento. Sin embargo, para determinar si el desempeño es un problema, necesita de perfil en lugar de obtener arbitraria respuestas de un foro de discusión.

  6. 22

    Hay cierta sobrecarga con la reflexión, pero es mucho más pequeño en la moderna VMs de lo que solía ser.

    Si usted está usando la reflexión para crear cada objeto simple en su programa, entonces algo está mal. Usando de vez en cuando, cuando usted tiene una buena razón, no debería ser un problema en absoluto.

  7. 7

    Reflexión es lento, a pesar de que la asignación de objetos no es tan desesperada como otros aspectos de la reflexión. El logro de un rendimiento equivalente con la reflexión basada en la creación de instancias requiere escribir el código para el jit puede decir que la clase se crea una instancia. Si la identidad de la clase no puede ser determinada, entonces la asignación de código puede no estar en línea. Peor aún, escapar de análisis de falla, y el objeto no puede ser asignado en la pila. Si tienes suerte, la JVM en tiempo de ejecución de perfiles puede venir al rescate, si este código se pone caliente, y se puede determinar de forma dinámica la clase que predomina y se puede optimizar para que uno.

    Ser conscientes de la microbenchmarks en este hilo son muy deficiente, por lo que tomar con un grano de sal. El menos imperfecto, por lejos, es Pedro Lawrey s: sí calentamiento corre a buscar los métodos jitted, y (conscientemente) derrota a escapar de análisis para asegurar que las asignaciones se están produciendo. Incluso que uno tiene sus problemas, sin embargo: por ejemplo, el enorme número de matriz de las tiendas se puede esperar la derrota de los cachés y almacenar los topes, así que esto va a terminar siendo en su mayoría una memoria de referencia si sus asignaciones son muy rápidos. (Felicitaciones a Pedro en llegar a la conclusión de derecho, sin embargo: que la diferencia es «150ns» en lugar de «2.5 x». Sospecho que hace este tipo de cosas para vivir.)

  8. 7

    Sí hay un impacto en el rendimiento cuando el uso de la Reflexión, pero una posible solución para optimización de almacenamiento en caché el método:

      Method md = null;     //Call while looking up the method at each iteration.
          millis = System.currentTimeMillis( );
          for (idx = 0; idx < CALL_AMOUNT; idx++) {
            md = ri.getClass( ).getMethod("getValue", null);
            md.invoke(ri, null);
          }
    
          System.out.println("Calling method " + CALL_AMOUNT+ " times reflexively with lookup took " + (System.currentTimeMillis( ) - millis) + " millis");
    
    
    
          //Call using a cache of the method.
    
          md = ri.getClass( ).getMethod("getValue", null);
          millis = System.currentTimeMillis( );
          for (idx = 0; idx < CALL_AMOUNT; idx++) {
            md.invoke(ri, null);
          }
          System.out.println("Calling method " + CALL_AMOUNT + " times reflexively with cache took " + (System.currentTimeMillis( ) - millis) + " millis");

    resultará en:

    [java] método de Llamada de 1000000 de veces reflexivamente con la búsqueda tomó 5618 millis

    [java] método de Llamada de 1000000 de veces reflexivamente con caché tomó 270 millis

    • La reutilización de método/constructor es realmente útil y de ayuda, pero tenga en cuenta que la prueba anterior no dar cantidades significativas debido a la costumbre de benchmarking problemas (sin calentamiento, así que el primer bucle, en particular, es en su mayoría de medición de la JVM/JIT el tiempo de calentamiento).
  9. 6

    Sí, es significativamente más lento. Se ejecuta el código que hice, y aunque no tengo las métricas disponibles en el momento, el resultado final fue que tuvimos para refactorizar el código para no utilizar la reflexión. Si usted sabe de que clase es, simplemente llame al constructor directamente.

    • +1 yo he tenido una experiencia similar. Es bueno asegúrese de que sólo utiliza la reflexión de si es absolutamente necesario.
    • por ejemplo, AOP basado en las librerías necesidad de reflexión.
  10. 6

    Curiosamente, erigiendo setAccessible(verdadero), que se salta los controles de seguridad, tiene un 20% de reducción en el costo.

    Sin setAccessible(true)

    new A(), 70 ns
    A.class.newInstance(), 214 ns
    new A(), 84 ns
    A.class.newInstance(), 229 ns

    Con setAccessible(true)

    new A(), 69 ns
    A.class.newInstance(), 159 ns
    new A(), 85 ns
    A.class.newInstance(), 171 ns
    • Me parece evidente, en principio. Hacer estos números escala linealmente, cuando se ejecuta 1000000 invocaciones?
    • En realidad setAccessible() puede tener mucho más la diferencia en general, especialmente para los métodos con múltiples argumentos, por lo que siempre debe ser llamado.
  11. 4

    En el doReflection() es la sobrecarga debido a la Clase.forName(«misc.A») (que requeriría una clase de búsqueda, potencialmente escaneo de la ruta de clases en el filsystem), en lugar de la newInstance() llamada en la clase. Me estoy preguntando lo que las estadísticas se vería como si la Clase.forName(«misc.A») se realiza sólo una vez fuera de la for-loop, que en realidad no tiene que ser hecho para cada invocación del bucle.

  12. 1

    Sí, siempre será más lento crear un objeto de reflexión ya que la JVM no puede optimizar el código en tiempo de compilación. Ver el Sol/Java Reflexión tutoriales para obtener más detalles.

    Ver esta simple prueba:

    public class TestSpeed {
        public static void main(String[] args) {
            long startTime = System.nanoTime();
            Object instance = new TestSpeed();
            long endTime = System.nanoTime();
            System.out.println(endTime - startTime + "ns");
    
            startTime = System.nanoTime();
            try {
                Object reflectionInstance = Class.forName("TestSpeed").newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            endTime = System.nanoTime();
            System.out.println(endTime - startTime + "ns");
        }
    }
    • Tenga en cuenta que usted debe separar la búsqueda (Class.forName()) de la instanciation (newInstance()), debido a que varían significativamente en sus características de rendimiento y ocasionalmente se puede evitar la reiterada búsqueda en un sistema bien diseñado.
    • También: usted necesita para ejecutar cada tarea, muchas, muchas veces para obtener un punto de referencia útil: la primera de todas las acciones son demasiado lentos para ser medido de forma fiable y en segundo lugar usted necesita para calentar el HotSpot VM para obtener números útiles.
  13. 1

    A menudo usted puede usar Apache commons BeanUtils o PropertyUtils que la introspección (básicamente que la caché de los datos de metadatos acerca de las clases, de modo que no siempre es necesario utilizar la reflexión).

  14. 0

    Yo creo que depende de cómo la luz/pesado el objetivo del método es. si el objetivo del método es muy ligero(por ejemplo, getter/setter), podría ser 1 ~ 3 veces más lento. si el método objetivo se tarda alrededor de 1 milisegundo o de arriba, a continuación, el rendimiento va a ser muy estrecha. aquí está la prueba que hice con Java 8 y reflectasm :

    public class ReflectionTest extends TestCase {    
    @Test
    public void test_perf() {
    Profiler.run(3, 100000, 3, "m_01 by refelct", () -> Reflection.on(X.class)._new().invoke("m_01")).printResult();    
    Profiler.run(3, 100000, 3, "m_01 direct call", () -> new X().m_01()).printResult();    
    Profiler.run(3, 100000, 3, "m_02 by refelct", () -> Reflection.on(X.class)._new().invoke("m_02")).printResult();    
    Profiler.run(3, 100000, 3, "m_02 direct call", () -> new X().m_02()).printResult();    
    Profiler.run(3, 100000, 3, "m_11 by refelct", () -> Reflection.on(X.class)._new().invoke("m_11")).printResult();    
    Profiler.run(3, 100000, 3, "m_11 direct call", () -> X.m_11()).printResult();    
    Profiler.run(3, 100000, 3, "m_12 by refelct", () -> Reflection.on(X.class)._new().invoke("m_12")).printResult();    
    Profiler.run(3, 100000, 3, "m_12 direct call", () -> X.m_12()).printResult();
    }
    public static class X {
    public long m_01() {
    return m_11();
    }    
    public long m_02() {
    return m_12();
    }    
    public static long m_11() {
    long sum = IntStream.range(0, 10).sum();
    assertEquals(45, sum);
    return sum;
    }    
    public static long m_12() {
    long sum = IntStream.range(0, 10000).sum();
    assertEquals(49995000, sum);
    return sum;
    }
    }
    }

    La prueba completa de código está disponible en GitHub:ReflectionTest.java

Dejar respuesta

Please enter your comment!
Please enter your name here