2011-10-25 27 views

Respuesta

9

La alternativa es evitar el uso instanceof y diseñar sus clases correctamente (en OO sentido).

Como el operador instanceof tiene una correspondiente instrucción de código de bytes "instanceof", probablemente no habrá un enfoque más eficaz; pero esto también puede depender de cómo se optimice la JVM real.

+5

Esto es más un comentario que una respuesta. La pregunta es esencialmente: "Para hacer X (donde X no se expresa) debo hacer Y, ¿qué tan rápido es Y y hay alternativas?" Propones no hacer X en absoluto, lo cual no está abordando el punto de OP. –

+1

@MichaelMcGowan: Desde mi experiencia, 'instanceof' a menudo está relacionado con un mal diseño. Para mí, no usarlo es la mejor alternativa. Y si no lo está usando, no necesita preocuparse por su rendimiento. – jeha

+0

Estoy totalmente de acuerdo en que * a menudo * está relacionado con un mal diseño. Sin embargo, eso no significa que siempre es el caso, y, a veces, por diversas razones, uno tiene un mal diseño. –

2

Si desea comprobar si el objeto es una instancia de una clase determinada (pero no si extends o implements ella), tal vez la comparación de las clases con == sería más rápido:

o.getClass() == YourClass.class 

De lo contrario ya que la instanceof palabra clave ha sido creada para este propósito específico No veo cómo podría hacerlo mejor ..

+1

No creo que esto sea más rápido, porque 'ref instanceof class' se asigna directamente a la operación de código byte' instanceof'. Su enfoque agrega el método llamado 'getClass'. –

+0

La comparación que está intentando con 'getClass' no funcionará cuando intente comprobar si el objeto también pertenece a una determinada subclase. Por ejemplo, si tiene 'FileReader' extendiendo' InputStreamReader' que a su vez extiende/implementa 'Reader', llamar' getClass' en un objeto instanciado con 'new FileReader' nunca rendirá nada más que la clase' FileReader', y entonces ' o.getClass() == Reader' o 'o.getClass() == InputStreamReader' ambos evaluarán a' false'. 'instanceof', por otro lado, arrojará' verdadero' en los tres casos de clase. – amn

2

Supongo que realmente ha perfilado su código y encontró que su uso de instanceof es un golpe de rendimiento no trivial? Si no es así, casi con seguridad estás resolviendo un problema que no merece la pena resolver.

Si todo lo que estamos haciendo es un código como éste:

if (something instanceof MyClass) { 
    MyClass mySomething = (MyClass) something; 
    //... 
} else { 
    //exceptional case 
} 

entonces podría ser posible tratar el elenco primera, y permitir que el ClassCastException que sea su "caso excepcional":

try { 
    MyClass mySomething = (MyClass) something; 
} catch (ClassCastException cce) { 
    //exceptional case 
} 

Ahora, aunque puede ser prematuro optimización, no sería prematuro repensar su diseño. El uso excesivo de instanceof es un olor de diseño. En general, debe usar genéricos y polimorfismos de manera que se reduzca la cantidad de veces que usaría instanceof (y de hecho, fundición) hasta (casi) cero.

  1. Si código diferente se debe ejecutar en función del tipo del objeto, considerar la posibilidad de que el código un método de instancia del objeto y que tiene los diferentes tipos se ajustan a una interfaz.

  2. Si te das cuenta de que un objeto es de cierto tipo pero has hecho algún paso que haga que el compilador pierda el rumbo de ese hecho (por ejemplo, lo pones en List crudo), podría ser un candidato para la genificación.

7

instanceof es bastante malditamente rápido. Sin embargo, generalmente es un síntoma de un diseño mal pensado.

Tendrá el mismo rendimiento que un elenco (exitoso), ya que está haciendo casi lo mismo. De hecho, la tarea es más o menos equivalente a una llamada a un método "virtual".

Implementaciones seguras: para las clases, solo se trata de obtener la clase de tiempo de ejecución y observar un desplazamiento fijo para verificar la superclase (siempre que no tenga una cadena de herencia de más de ocho clases para HotSpot) . Las interfaces son un poco más complicadas, pero generalmente tienen los últimos dos casos usados ​​para cualquier clase de tiempo de ejecución en caché. Entonces eso también es rápido.

Cuestiones relacionadas