2011-02-08 14 views
6

Me pregunto si el uso de tipos genéricos durante el programa tendrá un efecto degradante (significativo) en el rendimiento de la aplicación. Utilizo una gran cantidad de objetos de recopilación (listas, conjuntos, mapas) y para dar mejor flexibilidad a la aplicación (esta aplicación debe integrarse en otra aplicación). Usé solo tipos genéricos en lugar de parametrizarlos. ¿Es esta una práctica común o alguien tiene una sugerencia/consejo? ¿Habrá algún rendimiento significativo degradado?Tipo genérico y rendimiento

Gracias de antemano,

+0

¿Qué quiere decir exactamente con "tipos genéricos en lugar de parametrizarlos"? Creo que quisiste decir que estás usando tipos crudos (es decir, no especificas la información del tipo genérico). –

+0

Te sugiero que uses tipos específicos/parametrizados donde puedas, y siempre que mejore la claridad. –

+1

Incluso si el rendimiento fuera diferente, ¿cuál sería el costo en términos de tiempo de desarrollo y errores si utilizara el modo antiguo y no genérico con moldes y similares? Eso también es importante, y con características de lenguaje como genéricos, consideraciones de rendimiento más significativas que las reales. Si el rendimiento fuera una consideración, estaría enyesado en todas las descripciones y tutoriales sobre genéricos. – fwielstra

Respuesta

11

Habrá sin degradación del rendimiento en absoluto, ya que los genéricos son efectivamente un "truco en tiempo de compilación".

El compilador usa esta información para rechazar ciertas prácticas inseguras de tipo que de otro modo aparecerían en tiempo de ejecución, si no utilizan genéricos. Durante el tiempo de ejecución, solo se utilizan las clases sin formato (es decir, el límite superior de los parámetros genéricos), por lo que la ejecución será idéntica a y no a con los genéricos, y solo realice las clases usted mismo.

+1

Aunque podría compilarse un poco más lento;) –

1

El uso de genéricos no tiene un impacto significativo en el rendimiento o el consumo de memoria.

La prueba más fácil para esto es que la información de tipo genérico no está generalmente disponible en tiempo de ejecución. Eso significa que la JVM funciona exactamente igual cuando hay información de tipo genérico como si no hubiera ninguna.

Usar solo tipos brutos "para dar flexibilidad" es una receta para desastres, porque no tiene información de tipo en sus colecciones y por lo tanto puede pasar cualquier tipo de objeto, incluso si su código no está preparado para manejarlo (es decir, si su código espera una colección de objetos String, pero se pasa una colección con Integer en ella, lanzará un ClassCastException. Con genéricos (correctamente implementados) sería un error de tiempo de compilación).

2

tipos genéricos se prividing seguridad tipo (cualquier problema de tipo de fundición aparecerán durante el tiempo de compilación en tiempo de ejecución no) y son básicamente instrucciones al compilador que están más 'borrados' (borrado ) y no aparecen en esa forma (son reemplazados por moldes explícitos) durante el tiempo de ejecución. Por lo tanto, no hay penalización de rendimiento.

0

Todas sus definiciones de genéricos son solo de tiempo de diseño. Una vez que compila su programa, la JVM reemplaza todas sus definiciones por moldes. Este es un pequeño rendimiento en comparación con la codificación de su clase para contener el tipo correcto que necesita desde el principio y así evitar el reparto.

Pero la degradación en el rendimiento es pequeña y le recomiendo que use genéricos cuando sea apropiado para aumentar la legibilidad y la reutilización de su código. Por supuesto, puede considerar esto si tiene una clase con uso EXTREMO de métodos que harán estos moldes implícitos y está experimentando problemas de rendimiento. Aunque no antes que ;-).

2

Según lo explicado por otros colaboradores, en la mayoría de los casos, el uso de medicamentos genéricos no tendrá ningún impacto en el rendimiento. El único problema de rendimiento es cuando debe reemplazar un tipo primitivo por su tipo de objeto (por ejemplo, si necesita pasar int como parámetro genérico.

Sin embargo, a menos que haga un uso intensivo de su objeto, el la penalización de rendimiento no es visible. En consecuencia, debe comenzar con genérico y, si se produce un problema de rendimiento debido a este caso particular, puede reemplazar su objeto genérico por una clase que use el tipo primitivo. La optimización temprana es mala.

+0

Gracias a Nicholas por la frase "La optimización temprana es mala". Creo que estoy pendiente de esto y necesito salir de eso. Después de escribir un método, inmediatamente empiezo a preocuparme por su rendimiento y trato de inducir algunas "optimizaciones" siempre que sea posible – Ozyman

+0

Se puede diagnosticar como "optimización anticipada". Refactor, hazlo más claro, ejecútalo. Si parece lento, piénselo en un nivel algorítmico. Si no puede ser mejor, use trucos para optimizar los problemas marginales como "tipo primitivo como genéricos". – Nicolas

+0

Esto no tiene ningún sentido. Si tiene que usar un objeto bajo genéricos, también debe usar un objeto en el mismo lugar antes de los genéricos. p.ej. si utiliza un 'ArrayList ' ahora, entonces antes de que existieran los genéricos, aún tendría que poner un objeto 'Integer' en' ArrayList'. Usar un 'int' requeriría una clase separada, con y sin genéricos. – newacct

0

Por lo general, no, todo es magia de compilación. En algunos casos, puede existir un costo de tiempo de ejecución oculto.

class A<T> 
1  void f(T arg) 

    class B extends A<String> 
2  void f(String arg) 

    A<String> a = new B(); 
3 a.f("blah"); 

La línea 3 tendrá el método 2 invocado. Sin embargo, primero invoca el método 1, pero el método 2 no es un método tradicional de "anulación" de 1, las firmas son diferentes. Javac debe unir los dos, y en tiempo de ejecución hay un costo del método 1 al método 2.

El costo podría optimizarse a nada mediante la incorporación del método JVM.

Cuestiones relacionadas