¿Cuáles son las características de rendimiento de la reflexión 'is' en C#?[duplicar]

StackOverflow https://stackoverflow.com/questions/57701

  •  09-06-2019
  •  | 
  •  

Pregunta

Esta pregunta ya tiene respuesta aquí:

Es mostrado esa conversión de 'como' es mucho más rápida que la conversión de prefijo, pero ¿qué pasa con la reflexión de 'es'?¿Qué tan malo es?Como puedes imaginar, buscar "es" en Google no es muy efectivo.

¿Fue útil?

Solución

Hay algunas opciones:

  1. El elenco clasico: Foo foo = (Foo)bar
  2. El as operador de reparto: Foo foo = bar as Foo
  3. El is prueba: bool is = bar is Foo

  1. El elenco clasico necesita comprobar si bar se puede lanzar de forma segura a Foo (rápido) y luego hacerlo (más lento) o lanzar una excepción (muy lento).
  2. El as operador necesita comprobar si bar se puede lanzar, luego haz el lanzamiento, o si no se puede lanzar de manera segura, entonces simplemente regresa null.
  3. El is operador solo comprueba si bar se puede enviar a Foo y devolver un boolean.

El is La prueba es rápida porque solo realiza la primera parte de una operación de fundición completa.El as El operador es más rápido que una conversión clásica porque no genera una excepción si la conversión falla (lo que lo hace bueno para situaciones en las que legítimamente se espera que la conversión falle).

Si solo necesitas saber si la variable bares un Foo luego usa el is operador, PERO, si vas a probar si bar es un Foo, y de ser así, entonces lanzalo, entonces deberías usar el as operador.

Básicamente, cada elenco debe hacer el equivalente a un is Para empezar, verifique internamente para asegurarse de que el elenco sea válido.Entonces si haces un is verificación seguida de un yeso completo (ya sea un as cast, o con el operador de cast clásico) usted está haciendo efectivamente el is verifíquelo dos veces, lo cual supone un ligero gasto adicional.

Otros consejos

La forma en que lo aprendí es que esto:

if (obj is Foo) {
  Foo f = (Foo)obj;
  f.doSomething();
}

es más lento que esto:

Foo f = obj as Foo;
if (f != null) {
  f.doSomething();
}

¿Es lo suficientemente lento como para importar?Probablemente no, pero es algo tan sencillo a lo que hay que prestar atención, que bien podrías hacerlo.

"is" es básicamente equivalente al operador IL "isinst", que ese artículo describe como rápido.

Debería ser lo suficientemente rápido como para que no importe.Si está comprobando el tipo de objeto lo suficiente como para que tenga un impacto notable en el rendimiento, debe repensar su diseño.

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