2008-08-14 12 views
20

Dado un cuerpo de método vacío, el JIT optimizará la llamada (sé que el compilador de C# no lo hará). ¿Cómo voy a averiguarlo? ¿Qué herramientas debería usar y dónde debería estar mirando?En .NET, ¿se optimizarán las llamadas al método vacío?

Como estoy seguro de que se lo preguntará, el motivo del método vacío es una directiva de preprocesador.


@ Chris: tiene sentido, pero podría optimizar cabo llamadas al método. Así que el método todavía existiría, pero las llamadas estáticas podrían eliminarse (o al menos incluirse ...)

@Jon: Eso solo me dice que el compilador del lenguaje no hace nada. Creo que lo que tengo que hacer es ejecutar mi dll a través de ngen y mirar el conjunto.

Respuesta

1

No, los métodos vacíos nunca se optimizan. Aquí hay un par de razones por las cuales:

  • El método que se podría llamar de una clase derivados, tal vez en un montaje de diferente
  • El método podría ser llamado usando Reflexión (incluso si se marca privada)

Edit: Sí, desde la consulta de ese (excelente) código de proyecto doc, el JITer eliminará las llamadas a los métodos vacíos. Pero los métodos en sí mismos aún se compilarán y formarán parte de tu binario por las razones que enumeré.

1

Si todo sigue igual, sí, debe optimizarse. El JIT enumera las funciones cuando corresponde y hay algunas cosas más apropiadas que las funciones vacías :)

Si realmente quiere estar seguro, cambie su método vacío para lanzar una excepción e imprima el seguimiento de la pila que contiene.

12

Este capítulo tiene un buen tratamiento bastante de optimizaciones JIT, hacer una búsqueda en la página de 'método está vacío', que es aproximadamente la mitad de camino por el artículo -

http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx

métodos aparentemente vacío no consiguen optimizado mediante la incorporación de lo que efectivamente no es código.

@Chris: Me doy cuenta de que los métodos seguirán siendo parte del binario y que estas son optimizaciones JIT :-). En una nota semi-relacionados, Scott Hanselman tenía bastante un interesante artículo sobre procesos en línea en la liberación de las pilas de llamadas de construcción:

http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx

0

@ Jon Limjap: Ya sabemos que el compilador de C# no optimiza métodos vacíos a cabo. Dado que lo que está descompilando con ildasm fue generado por el compilador C# ... no hay ayuda allí.

10

supongo que su código es como:

void DoSomethingIfCompFlag() { 
#if COMPILER_FLAG 
    //your code 
#endif 
} 

Esto no quede optimizado, sin embargo:

partial void DoSomethingIfCompFlag(); 

#if COMPILER_FLAG 
partial void DoSomethingIfCompFlag() { 
    //your code 
} 
#endif 

El primer método vacío es parcial, y el compilador de C# 3 lo optimizará


Por cierto: esto es básicamente para lo que son los métodos parciales. Microsoft agregó generadores de código a sus diseñadores Linq que necesitan llamar a métodos que por defecto no hacen nada.

En lugar de forzarlo a sobrecargar el método, puede usar un parcial.

De esta manera, los parciales están completamente optimizados si no se utilizan y no se pierde el rendimiento, en lugar de agregar la sobrecarga de la llamada al método vacío adicional.

+1

El uso del atributo [Conditional ("COMPILER_FLAG")] tendrá el mismo efecto y quizás sea un poco más fácil de usar. Ver http://msdn.microsoft.com/en-us/library/4xssyw96.aspx – Eric

Cuestiones relacionadas