2012-06-13 18 views
14

Una pregunta académica: he comentado que una clase que escribí en un servicio de WCF es muy larga (~ 3000 líneas) y debe dividirse en otra más pequeña. clasesSobrecarga de rendimiento del tamaño de clase grande en C#

El alcance del servicio ha crecido con el tiempo y los métodos que contiene contienen muchas funciones similares, por lo que no creo varias clases más pequeñas hasta ahora, así que no tengo ningún problema para hacerlo (aparte del tiempo que tomará ¡hazlo!), pero me hizo pensar: ¿hay una sobrecarga de rendimiento significativa al usar una única clase grande en lugar de múltiples clases más pequeñas? Si es así, ¿por qué?

+5

Eso realmente depende de cómo se usa y de lo que hace ... y cómo está escrito. Sin embargo, creo que debería haber menos preocupaciones sobre la sobrecarga del rendimiento que sobre la sobrecarga de la memoria. –

+3

"¿hay una sobrecarga de rendimiento significativa en el uso de una única clase grande en lugar de múltiples clases más pequeñas?" - ** No ** ** PERO ... Es simplemente un diseño pobre. A veces no puedes evitarlo, pero parece que en este caso puedes. ** –

+0

Rendimiento, ¿en qué sentido, serialización? En ese caso, tal vez, si al violar una sola responsabilidad estás forzando a enviar información innecesaria. Principalmente, la preocupación es la mantenibilidad. – HackedByChinese

Respuesta

19

No hará ninguna diferencia notable. Antes de siquiera pensar en una micro-optimización tan extrema, debería pensar en la facilidad de mantenimiento, que está bastante en peligro con una clase de aproximadamente 3000 LOC.

Escriba primero su código de manera que sea correcto y fácil de mantener. Solo si realmente se encuentra con problemas de rendimiento, primero debe perfilar su aplicación antes de tomar decisiones sobre las optimizaciones. Por lo general, los cuellos de botella de rendimiento se encontrarán en otro lugar (falta de paralelización, malos algoritmos, etc.).

+0

Muy cierto, con múltiples desarrolladores trabajando en la clase, estoy sorprendido de que se haya hecho tan grande tan rápido. Hemos probado la carga del servicio y está funcionando muy bien, de ahí mi interés en averiguar si habría una ganancia desde esa perspectiva, pero la capacidad de administración aumentaría efectivamente a través de la refactorización. ¡Gracias! – aaaaa

8

No, tener una clase grande no debería afectar el rendimiento. La división de una clase grande en clases más pequeñas podría incluso reducir el rendimiento ya que tendrá más redirecciones. Sin embargo, el impacto es insignificante en casi todos los casos.

El objetivo de dividir una clase en partes más pequeñas no es mejorar el rendimiento sino facilitar la lectura, modificación y mantenimiento del código. Pero esto solo es motivo suficiente para hacerlo.

1

No diría que hay problemas de rendimiento, sino problemas de legibilidad en el mantenimiento. Es mucho más fácil modificar más clases que cada una de ellas realizar su propósito que trabajar con una sola clase monstruosa. Eso es simplemente ridículo. Estás rompiendo todos los principios de OOP al hacerlo.

por lo tanto, yo no la creación de múltiples clases más pequeñas hasta ahora, así que no tengo problema con hacerlo

precisamente el caso que he estado advirtiendo de varias veces al ya tan ... Personas tienen miedo de la optimización prematura, pero no tienen miedo de escribir un código incorrecto con una idea como "Lo arreglaré más tarde cuando se convierta en un problema". Déjame decirte algo: más de 3000 clases LOC ya es un problema, no importa el impacto en el rendimiento, si corresponde.

7

Las consideraciones de rendimiento son la última de sus preocupaciones cuando se trata de la decisión de agregar un puñado de clases bien diseñadas en un solo archivo fuente. Piense más en:

  • Capacidad de mantenimiento ... Es difícil hacer arreglos de punto en tanto código.
  • Legibilidad ... Si tiene que desplazarse hacia arriba y hacia abajo como un demonio al llegar a cualquier parte, no es legible.
  • Reusabilidad ... Sin descomposición hace las cosas difíciles de reutilizar.
  • Cohesion ... Si está haciendo demasiadas cosas en una sola clase, probablemente no sea coherente de ninguna manera.
  • Testabilidad ... Unidad de buena suerte probando un lote de 3.000 LoC de código de espagueti a cualquier nivel razonable de cobertura.

Podría seguir, pero la mentalidad de los grandes archivos fuente individuales parece remontarse a la era de programación de VB/Procedureal. Hoy en día, empiezo a tener miedo si un método tiene una complejidad ciclomática de más de 15 y una clase tiene más de un par de cientos de líneas.

Normalmente encuentro que si refactorizo ​​una de estas 10k líneas de código de behemoths, la suma total de las líneas de código de las nuevas clases termina siendo 40% del original si no menos. Más clases y descomposición (dentro de lo razonable) conducen a menos código. Contraintuitivo al principio, pero realmente funciona.

+0

Afortunadamente, hemos utilizado regiones para dividir lógicamente el código y reducir el escenario de subida/bajada de página, ahora estoy refaccionando en clases separadas utilizando esas regiones como base, ¡gracias! – aaaaa

+0

Aunque me gustan las regiones, las críticas a Microsoft son que causan más problemas de los que resuelven al "ocultar el problema" del código inflado. –

+1

Me gustan las regiones pero solo para separar mi clase por constructores, dependencias, configuraciones, estado y métodos. Me ayuda a mantener separadas estas propiedades y métodos conceptuales. –

1

Depende de cómo se usa la clase y con qué frecuencia se crea una instancia. Cuando la clase se crea una instancia una vez, p. clase de servicio de contrato, que la sobrecarga de rendimiento típica no es significativa.

Cuando la clase se instanciará a menudo, de lo que podría reducir el rendimiento.

Pero en este caso, no pienses en el rendimiento, piensa en el diseño. Mejor pensar en soporte y mayor desarrollo y capacidad de prueba. Las clases de 3K LOC son enormes y, por lo general, libros de anti-patrones. Dichas clases conducen a la duplicación de código y errores, el desarrollo posterior será doloroso y causa que los errores ya corregidos aparezcan una y otra vez, el código es frágil.

Por lo tanto, la clase definitivamente debe ser refactorizada.

3

El problema real no es la sobrecarga de rendimiento. La sobrecarga está en mantenibilidad y reutilización. Es posible que tenga los principios de SOLID del diseño orientado a objetos, algunos de los cuales implican que las clases más pequeñas son mejores. En particular, miraría el Principio de Responsabilidad Individual, el Principio Abierto/Cerrado y el Principio de Sustitución de Liskov, y ... en realidad, pensándolo bien, todos implican que las clases más pequeñas son mejores, aunque indirectamente.

Esto no es fácil de 'obtener'. Si ha estado programando con un lenguaje OO mientras mira SOLID y de repente tiene mucho sentido. Pero hasta que las bombillas se encienden, puede parecer un poco oscuro.

En una nota mucho más simple, tener varias clases, con un archivo por clase, cada una sensatamente llamada para describir el comportamiento, donde cada clase tiene un solo trabajo, tiene que ser más fácil de manejar desde una perspectiva de cordura pura que una larga página de 3.000 líneas.

Y luego considere si una parte de su clase de 3.000 líneas podría ser útil en otra parte de su programa ... poner esa funcionalidad en una clase dedicada es una manera excelente de encapsularla para su reutilización.

Básicamente, mientras escribo, me doy cuenta de que, de todos modos, me estoy burlando de los aspectos de SOLID. Probablemente sea mejor que lea straight from the horses mouth on this.

Cuestiones relacionadas