usar una son qué objetos métodos metodos metodo los llamar estáticos estaticos ejemplos cuando clases clase c# performance static-methods il

una - metodos estaticos c#



Rendimiento de métodos estáticos vs métodos de instancia (3)

Mi pregunta está relacionada con las características de rendimiento de los métodos estáticos frente a los métodos de instancia y su escalabilidad. Suponga para este escenario que todas las definiciones de clase se encuentran en un único ensamblaje y que se requieren múltiples tipos de punteros discretos.

Considerar:

public sealed class InstanceClass { public int DoOperation1(string input) { // Some operation. } public int DoOperation2(string input) { // Some operation. } // … more instance methods. } public static class StaticClass { public static int DoOperation1(string input) { // Some operation. } public static int DoOperation2(string input) { // Some operation. } // … more static methods. }

Las clases anteriores representan un patrón de estilo de ayuda.

En una clase de instancia, resolver el método de instancia requiere un momento para hacer lo contrario a StaticClass.

Mis preguntas son:

  1. Cuando mantener el estado no es una preocupación (no se requieren campos o propiedades), ¿siempre es mejor utilizar una clase estática?

  2. Donde hay un número considerable de estas definiciones de clases estáticas (digamos 100, por ejemplo, con un número de métodos estáticos cada una) ¿afectará esto el rendimiento de la ejecución o el consumo de memoria de forma negativa en comparación con el mismo número de definiciones de clase de instancia?

  3. Cuando se llama a otro método dentro de la misma clase de instancia, ¿aún se produce la resolución de la instancia? Por ejemplo, usando la palabra clave [this] como esta. this.DoOperation2("abc") desde DoOperation1 de la misma instancia.


Cuando mantener el estado no es una preocupación (no se requieren campos o propiedades), ¿siempre es mejor utilizar una clase estática?

Yo diría que sí. Al declarar algo static , declaras un intento de ejecución sin estado (no es obligatorio, sino un intento de algo que uno esperaría)

Donde hay un número considerable de estas clases estáticas (digamos 100, por ejemplo, con una cantidad de métodos estáticos cada una) ¿afectará esto el rendimiento de la ejecución o el consumo de memoria de forma negativa en comparación con el mismo número de clases de instancia?

No lo crea, a menos que esté seguro de que las clases estáticas son realmente inexistentes, ya que de lo contrario es fácil desordenar las asignaciones de memoria y obtener pérdidas de memoria.

Cuando la palabra clave [this] se usa para llamar a otro método dentro de la misma clase de instancia, ¿aún se produce la resolución de la instancia?

No estoy seguro de este punto (este es un detalle de implementación pura de CLR), pero creo que sí.


En teoría, un método estático debería funcionar un poco mejor que un método de instancia, en igualdad de condiciones, debido a la ocultación adicional de this parámetro.

En la práctica, esto hace tan poca diferencia que se ocultará en el ruido de varias decisiones del compilador. (Por lo tanto, dos personas podrían "probar" una mejor que la otra con resultados en desacuerdo). No menos importante ya que this normalmente se pasa en un registro y, a menudo, se encuentra en ese registro para comenzar.

Este último punto significa que, en teoría, deberíamos esperar un método estático que tome un objeto como parámetro y haga algo con él para ser ligeramente menos bueno que el equivalente como una instancia en ese mismo objeto. Sin embargo, una vez más, la diferencia es tan pequeña que si intentas medirla probablemente terminarías midiendo alguna otra decisión del compilador. (Especialmente porque la probabilidad de que esa referencia esté en un registro todo el tiempo es bastante alta también).

Las diferencias reales de rendimiento dependerán de si tienes artificialmente objetos en la memoria para hacer algo que naturalmente debería ser estático, o estás enredado en cadenas de objetos que pasan de formas complicadas para hacer lo que naturalmente debería ser una instancia.

Por lo tanto, para el número 1. Cuando mantener el estado no es una preocupación, siempre es mejor ser estático, porque para eso está la estática . No es una cuestión de rendimiento, aunque hay una regla general de jugar muy bien con las optimizaciones del compilador: es más probable que alguien se haya esforzado por optimizar los casos que surgen con un uso normal que aquellos que tienen un uso extraño.

Número 2. No hace diferencia. Hay una cierta cantidad de costo por clase para cada miembro en términos de la cantidad de metadatos que hay, la cantidad de código que hay en el archivo DLL o EXE real y la cantidad de código jipeado que habrá. Esto es lo mismo ya sea de instancia o estático.

Con el elemento 3, this es lo que hace. Sin embargo nota:

  1. El parámetro this se pasa en un registro particular. Cuando se llama a un método de instancia dentro de la misma clase, probablemente ya estará en ese registro (a menos que esté oculto y el registro se use por algún motivo) y por lo tanto no se requiere acción para establecerlo en lo que necesita establecerse a. Esto se aplica en cierta medida a, por ejemplo, los primeros dos parámetros del método siendo los primeros dos parámetros de una llamada que realiza.

  2. Como quedará claro que this no es nulo, esto se puede usar para optimizar las llamadas en algunos casos.

  3. Como quedará claro que this no es nulo, esto puede hacer que las llamadas al método inline sean más eficientes otra vez, ya que el código producido para simular la llamada al método puede omitir algunas comprobaciones nulas que de todos modos podrían necesitar.

  4. Dicho esto, los controles nulos son baratos.

Vale la pena señalar que los métodos estáticos genéricos que actúan sobre un objeto, en lugar de los métodos de instancia, pueden reducir algunos de los costos discutidos en http://www.bluebytesoftware.com/blog/2011/10/23/OnGenericsAndSomeOfTheAssociatedOverheads.aspx en el caso donde esa estática dada no es llamada para un tipo dado. Como él lo dice "Por un lado, resulta que los métodos de extensión son una excelente manera de hacer que las abstracciones genéricas paguen más por jugar".

Sin embargo, tenga en cuenta que esto se relaciona solo con la creación de instancias de otros tipos utilizados por el método, que de otro modo no existirían. Como tal, realmente no se aplica a muchos casos (algún otro método de instancia utilizado de ese tipo, algún otro código en otro lugar usó ese tipo).

Resumen:

  1. En su mayoría, los costos de rendimiento de la instancia frente a la estática son inferiores a insignificantes.
  2. Por lo general, los costos que vendrá serán aquellos en los que abuse de la estática o viceversa. Si no lo hace parte de su decisión entre la estática y la instancia, es más probable que obtenga el resultado correcto.
  3. Existen casos excepcionales en que los métodos genéricos estáticos en otro tipo generan menos tipos creados que los métodos genéricos de instancia, lo que puede hacer que a veces tenga un pequeño beneficio para usar rara vez (y "rara vez" se refiere a los tipos con los que se usa en el duración de la aplicación, no con qué frecuencia se la llama). Una vez que entiendas de lo que está hablando en ese artículo, verás que es 100% irrelevante para la mayoría de las decisiones estáticas contra instancia de todos modos. Editar: Y en su mayoría solo tiene ese costo con ngen, no con el código jitted.

Editar: Una nota sobre cuán baratos son los null-cheques (que dije antes). La mayoría de los controles nulos en .NET no comprueban nulo en absoluto, sino que continúan lo que iban a hacer con la suposición de que funcionará, y si ocurre una excepción de acceso, se convierte en una NullReferenceException . Como tal, principalmente cuando conceptualmente el código C # implica una verificación nula porque está accediendo a un miembro de instancia, el costo si tiene éxito es realmente cero. Una excepción serían algunas llamadas en línea, (porque quieren comportarse como si llamaran a un miembro de instancia) y solo tocan un campo para activar el mismo comportamiento, por lo que también son muy baratas, y de todos modos a menudo pueden omitirse. (por ejemplo, si el primer paso en el método implicaba acceder a un campo tal como estaba).


los métodos estáticos son más rápidos pero menos OOP, si va a usar patrones de diseño de código estático probable, para escribir mejor la lógica de negocios sin funciones comunes y estáticas como lectura de archivos, WebRequest, etc. mejor darse cuenta como estático ... sus preguntas no tienen universal responder