2011-11-15 6 views
6

Un constructor estático se ejecuta la primera vez que accede a un miembro estático. Sabiendo esto, tengo varias preguntas:¿Puede un constructor estático reducir el rendimiento del acceso a métodos estáticos?

  • ¿Esto significa que cada vez que accedo a un método estático, el tiempo de ejecución debe verificar si se ha llamado al constructor estático?
  • ¿Esto genera un golpe de rendimiento?
  • ¿Las clases estáticas "sin constructor" evitan este golpe de rendimiento?

[EDIT]: Me gustaría aclarar que no estoy preocupado con micro-optimización.
Estoy haciendo esta pregunta porque es una decisión de diseño . Si un constructor estático incurre en un impacto en el rendimiento, entonces diseñaré mi código teniendo esto en cuenta y estaré más al tanto de las decisiones que pueden afectar el rendimiento.

Aquí hay un ejemplo para ilustrar mi pregunta. ¿Habría algún beneficio de tomar el método Independent y ponerlo en una clase estática separada? De esta forma, no tendría que verificar si se había inicializado el Test estático. [Actualización Consulte mi respuesta a continuación para obtener un ejemplo mejor y más simple].

static class Test { 
    // Static constructor with dependent method: 
    static int x; 
    static Test() { x = 5; } 
    static int Dependent() { return x; } 

    // Static, independent method: 
    static int Independent(int y) { return y+1; } 
} 

Here's the quote de la C# especificación sobre el constructor estático:

La ejecución de un constructor estático se desencadena por la primera de las siguientes eventos a ocurrir dentro de un dominio de aplicación:

  • Se crea una instancia de la clase.
  • Se hace referencia a cualquiera de los miembros estáticos de la clase.
+0

Posible duplicado: http://stackoverflow.com/questions/2921828/static-constructors-cause-a-performance-over-head –

+0

He leído esa publicación, pero definitivamente difiere de mi pregunta. Compara el rendimiento de ** type-initialization ** vs ** static constructor **. Me interesa saber si un constructor estático ralentiza el acceso a un método. ¡Releí el "duplicado", incluidas todas las respuestas Y enlaces, y todavía no tengo una respuesta a mi pregunta! –

+0

Creo que está en el campo de acceso y no en la llamada al método. Pero sí, puede haber una reducción notable del rendimiento en algunos escenarios. – CodesInChaos

Respuesta

7

Debido a la falta de respuestas, y bajo la dirección de @ Jobo, decidí probar esto por mí mismo.

Éstos son mis clases de prueba:

static class WithConstructor { 
    static WithConstructor(){ } 
    public static int Square(int x){ return x*x; } 
} 
static class NoConstructor { 
    public static int Square(int x){ return x*x; } 
} 

compilado para la liberación, utilizando .NET 4.0, los resultados fueron muy consistentes:

 
╔═════════════╦══════════════════╦═════════╦═══════════════╗ 
║ Iterations: ║ With Constructor ║ 4513 ms ║ Improvement: ║ 
║ 1000000000 ║ No Constructor ║ 3072 ms ║ 33%   ║ 
╚═════════════╩══════════════════╩═════════╩═══════════════╝ 

Por lo tanto, voy a responder a mis propias preguntas:

  • Si existe un constructor estático, a continuación, un método estático incurrirá en un (microscópica) rendimiento golpeado, porque la bandera beforefieldinit siempre debe estar marcada.

  • Si un constructor estático no existe, entonces el método no incurrirá en el golpe de rendimiento.

2

¿Por qué no probarlo usted mismo?

Llame a su método independiente varias veces como se especifica arriba. Luego crea una clase estática propia con el mismo método y llámala la misma cantidad de veces.

Utilice http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx para medir.

Mi conjetura sería que postulante no importa ...

También podría escribir algo a la consola en su constructor estático para comprobar si había sido llamado. Descubrir por ti mismo durará más que alguna respuesta teórica, solo mis 2 centavos.

+0

Creo que lo haré. Estoy realmente sorprendido de que no haya una respuesta conocida. –

+0

@Scott no hay una respuesta conocida porque es muy probable que esto no sea un cuello de botella para nadie. Incluso hay una posibilidad de que elimine ese constructor y, en su defecto, el valor de X en 5. – Rangoric

+0

@Rangoric No mencioné esto en mi OP (está ahí ahora), pero no estoy tan interesado en el rendimiento como estoy en las decisiones de diseño. Al diseñar un método estático, definitivamente ayuda a comprender posibles resultados de rendimiento, y en este caso, tener un buen patrón de diseño ayudará a evitar estos impactos. –

0

El constructor estático puede reducir el rendimiento del primer método que llama. Indead, la primera persona que llama se cambia para probar si ya se ha llamado al constructor estático, pero a otra persona que llama si no se ve afectado.

Cuestiones relacionadas