2010-11-06 15 views
5

Quiero saber si hay un efecto en la eficacia del programa al adoptar un enfoque orientado a objetos a un problema en comparación con el enfoque de programación estructurada en cualquier lenguaje de programación, pero especialmente en C++.Eficiencia del programa

Respuesta

3

Recuerdo que a principios de la década de 1990, cuando C++ era joven, se hicieron estudios al respecto. Si mal no recuerdo, los tipos que tomaron (bien escritos) programas C++ y los recodificaron en C obtuvieron un aumento del 15% en la velocidad. Los chicos que tomaron los programas C y los recodificaron en C++, y modificaron el estilo imperativo de C a un estilo OO (pero los mismos algoritmos) para C++ obtuvieron el mismo o mejor rendimiento. La aparente contradicción fue explicada por la observación de que los programas C, al ser traducidos a un estilo orientado a objetos, se organizaron mejor. Las cosas que hiciste en C porque era demasiado código y problemas para hacerlo mejor podrían hacerse más fácilmente de forma adecuada en C++.

Pensando en esto me pregunto acerca de la conclusión. Escribir un programa por segunda vez siempre dará como resultado un mejor programa, por lo que no tuvo que ser imperativo para el estilo OO que marcó la diferencia. Las arquitecturas informáticas de hoy en día están diseñadas con soporte de hardware para operaciones comunes realizadas por programas OO, y los compiladores han mejorado al usar las instrucciones, por lo que creo que es probable que cualquier sobrecarga que tenga una función virtual en 1992 sea mucho más pequeña hoy en día.

+0

Bonita anécdota. Muchos/la mayoría de los programadores fallarían al escribir ASM manual frente a un compilador moderno de C en términos de código de máquina eficiente de generación :-) –

+0

No tiene sentido comparar el costo de tiempo de ejecución de una función virtual con el costo de tiempo de ejecución de una función normal porque hacen diferentes cosas. Sí, la búsqueda binaria es un orden de magnitud más rápida que la ordenación rápida, pero sería una idea terrible utilizar la búsqueda binaria para ordenar un contenedor :) Si necesita una función virtual, necesita una función virtual. C++ proporciona funciones virtuales a un costo que es al menos tan bajo como simularlas en C. puro. Si hubiera una forma más económica de implementarlas, Bjarne Stroustrup lo habría descubierto hace mucho tiempo. – fredoverflow

+1

@Fred: a menos que Koenig lo venza. –

7

Quizás. Tal vez no.

Puede escribir código eficiente orientado a objetos. Puede escribir código estructurado ineficiente.

Depende de la aplicación, de qué tan bien se escribe el código y de la cantidad de código optimizado. En general, debe escribir código para que tenga una arquitectura modular buena y limpia, y esté bien diseñado; luego, si tiene problemas con el rendimiento, optimice los puntos críticos que causan problemas de rendimiento.

Utilice la programación orientada a objetos donde tenga sentido usarla y usar programación estructurada donde tenga sentido usarla. No tiene que elegir entre uno y otro: puede usar ambos.

+1

¡Y en casos realmente depende si usas un buen algoritmo (o muerte cerebral)!Solo quería agregar esto, porque ** un código bien escrito que utiliza un enfoque/algoritmo inapropiado puede ser terriblemente lento **, incluso si está muy "optimizado". –

1

No tiene que ser así, si tiene mucho cuidado para evitarlo. Si solo adopta el enfoque más directo, utilizando asignación dinámica, funciones virtuales y (especialmente) pasando objetos por valor, entonces sí habrá ineficiencia.

+0

Ineficiencia de FSVO :-) –

+0

@pst: Tal vez, pero hay un costo mucho mayor, por ej. funciones virtuales que la llamada de función. La reescritura utilizando CRTP permite más oportunidades de optimización y alineación, lo que podría significar un ahorro mucho mayor que las llamadas directas frente a las llamadas virtuales. –

1

No tiene que ser así. Algoritmo es todo lo que importa Estoy de acuerdo en que la encapsulación lo retrasará un poco, pero los compiladores están ahí para optimizar.

+3

Algoritmo es todo lo que importa - No estoy de acuerdo. El hardware moderno no siempre es adecuado para algunos algoritmos. – Anycorn

+2

No es lo único que importa (creo que es una cuantificación tonta), sino +1 para señalar que también es el enfoque/algoritmo utilizado y no solo qué tan "bien escrito" u "optimizado" o cuántas "instrucciones por segundo" el el código es/puede hacer. –

1

Diría que no si esta es la pregunta en el documento de ciencias de la computación.

Sin embargo, en el entorno de desarrollo real esto tiende a ser cierto si el paradigma de OOP se utiliza correctamente. La razón es que en un proceso de desarrollo real, generalmente necesitamos mantener nuestra base de códigos y el momento en que el paradigma de OOP podría ayudarnos. Un punto fuerte de OOP sobre programación estructurada como C es que en OOP es más fácil hacer que el código sea mantenible. Cuando el código es más fácil de mantener, significa menos errores y menos tiempo para corregir errores y menos tiempo para implementar nuevas funciones. La conclusión es que tendremos más tiempo para enfocarnos en la eficiencia de la aplicación.

+0

En realidad, no veo a nadie enfocarse en la eficiencia de la aplicación, excepto en formas que no importan. Cuando el rendimiento es tan malo que, incluso con sus máquinas veloces, se dan cuenta, lo que escucho es "Creo que es mejor que perfilemos, ¿qué perfilador deberíamos usar?" Si son diligentes, obtienen algo de perfilador, encuentran algo para obtener una aceleración del 10%, comentan lo bueno que es el generador de perfiles, y afirman que el código realmente debe estar haciendo muchas cosas buenas de manera eficiente y es por eso que lleva tiempo. Ese es el "Enfoque en la eficiencia" del que soy testigo. –

0

Podría haber: el enfoque de OO tiende a estar más cerca de un enfoque desacoplado donde los diferentes módulos no van hurgando uno dentro del otro. Están restringidos a interfaces públicas, y siempre hay un costo potencial en eso. Por ejemplo, llamar a un getter en lugar de solo examinar directamente una variable; o llamando a una función virtual por defecto porque el tipo de un objeto no es lo suficientemente obvio para una llamada directa.

Dicho esto, hay varios factores que disminuyen esto como una observación útil.

  1. un programa estructurado bien escrito deben tener la misma modularidad (es decir, implementaciones de ocultación), y por lo tanto incurrir en los mismos costes de indirección. El costo de llamar a un puntero de función en C probablemente sea muy similar al costo de llamar a una función virtual en C++.

  2. JIT modernos, e incluso el uso de métodos en línea en C++, puede eliminar el costo indirecto.

  3. Los costos en sí mismos son probablemente relativamente pequeños (normalmente solo unas pocas operaciones simples por llamada de instrucción). Esto será insignificante en un programa donde el trabajo real se realiza en bucles estrechos.

  4. Por último, un estilo más modular libera al programador para hacer frente a más complicado, pero es de esperar menos complejos algoritmos sin el peligro de errores de bajo nivel.

1

El problema no es técnico, es psicológico. Es en lo que te alienta a hacer haciéndolo más fácil.

Para hacer una analogía mundana, es como una tarjeta de crédito. Es mucho más eficiente que escribir cheques o usar efectivo. Si es así, ¿por qué las personas se meten en problemas con las tarjetas de crédito? Porque son tan fáciles de usar que abusan de ellos. Se necesita una gran disciplina para no usar en exceso algo bueno.

La forma OO se abusa es por

  • Creación demasiados "capas de abstracción"

  • Creación de estructura de datos demasiado redundante

  • Fomentar el uso de código de estilo notificación , intentando mantener la coherencia dentro de las estructuras de datos redundantes.

Es mejor para minimizar la estructura de datos, y si tiene que ser redundante, sea capaz de tolerar la inconsistencia temporal.

AGREGADO: Como una ilustración del tipo de cosas que OO alienta, esto es lo que veo a veces en la optimización del rendimiento: Alguien establece SomeProperty = true;. Eso suena bastante inocente, ¿verdad? Bueno, eso puede afectar a los objetos que contienen ese objeto, a menudo a través de un polimorfismo que es difícil de rastrear. Eso puede significar que alguna lista o diccionario en alguna parte necesita tener cosas agregadas o eliminadas de ella. Eso puede significar que se necesitan agregar o eliminar o barajar algunos controles de árbol o de control de lista. Eso puede significar que las ventanas están siendo creadas o destruidas. También puede significar que algunas cosas deben cambiarse en una base de datos, que puede no ser local, por lo que hay que realizar cierto bloqueo de E/S o de exclusión mutua.

Realmente puede volverse loco. ¿Pero a quién le importa? Es abstract.

+0

No obtuve adecuadamente su explicación adicional en la sección AÑADIDO, pero los puntos dados anteriormente fueron muy buenos. Y la analogía fue genial –

+0

@sandeepan: Es solo el tipo de cosas que veo. Como una propiedad 'Modificada' que determina si algo quiere ser guardado. Si está configurado como 'verdadero', puede ser interceptado por una clase principal y causar todo tipo de actividad que nunca adivinarías. Si está configurado como 'falso ', puede propocionarlo a un grupo de variables miembro, con una ola similar de actividad imprevista. Obtienes un grupo de gente que contribuye con el código de un proyecto, y todos hacen las cosas al estilo "OO", y eso es lo que tiendes a ver. –