El esplendor y la pobreza de la OLP

 

Clase base, varios descendientes, se utiliza uno de los descendientes, dependiendo de los parámetros establecidos en el inicio. Este es un principio bien conocido del funcionamiento universal de los programas. No importa cuántas variantes pueda haber (es decir, clases descendientes), se supone que este caso funciona muy rápido porque no hay llamadas if y switch que cambien el funcionamiento del programa, sólo una vez se selecciona la clase descendiente requerida durante la inicialización y entonces todo funciona de forma directa y sencilla.

class CBase{
   private:
   public:
      virtual void Fun(){
      
      }
};

class CClass1:CBase{
   private:
   public:
      void Fun(){
      
      }
};

CClass1 * cl;

void OnInit(){

   cl=new CClass1;

}

Sin embargo...

¿Cuántas variantes diferentes puede haber? ¿Un número razonable? 10, 20, 100? Incluso con 100 variantes, switch funciona más rápido que OOP.

Aquí hay un script para comparar el rendimiento. Compara la OOP anterior y un simple interruptor con funciones (y se llaman dos funciones, una de las llamadas a la función puede ser fácilmente descartada).

void ff(int z){

      switch(z){
         case 0:
         f0();
         break;

         ...

         case 99:
         f99();
         break;

      }
     
}
Los resultados (llamada f99):

Archivos adjuntos:
test.mq4  9 kb
 
Integer:

¿Cuántas opciones diferentes puede haber? ¿Un número razonable? 10, 20, 100? Incluso con 100 opciones, switch funciona más rápido que OOP.

Me gustaría advertir contra las generalizaciones excesivas: es razonable esperar este efecto en mql, porque utiliza "pseudopuntadores" virtuales - esencialmente manejadores que se refieren a la tabla hash interna (oculta) de direcciones reales. Para resolver estos punteros, se necesita una cantidad significativa de tiempo extra, mucho más que el direccionamiento directo de punteros. No he medido, pero es probable que el mismo efecto de "embotellamiento" de punteros se encuentre en los lenguajes dotNET y otras implementaciones similares.

Los lenguajes con punteros "reales" no tendrán este efecto, el interruptor perderá ahí - cuanto mayor sea la lista de opciones.

Así que la OOP no tiene esencialmente nada que ver...

 
MetaDriver:

Me gustaría advertir contra la sobregeneralización. Es razonable esperar tal efecto en mql, porque utiliza "pseudopuntos" virtuales - esencialmente tablas hash que se refieren a la tabla hash interna (oculta) de direcciones reales. Para resolver estos punteros, se necesita una cantidad significativa de tiempo extra, mucho más que el direccionamiento directo de punteros. No he medido, pero es probable que el mismo efecto de "embotellamiento" de punteros se encuentre en los lenguajes dotNET y otras implementaciones similares.

En lenguajes con punteros "reales" este efecto no se producirá, el interruptor perderá - cuanto mayor sea la lista de opciones.

Así que la OOP no tiene esencialmente nada que ver...

Está claro que es el propio compilador, de ahí que con una compilación "correcta" los tiempos de ejecución de los ejemplos anteriores se igualarían.
 
icas:
Está claro que sólo es cuestión del propio compilador, de ahí que si los ejemplos anteriores se compilan "correctamente", los tiempos de ejecución se igualarán.
El concepto de "corrección" depende de las normas, por lo que no tiene sentido. ;)
 

Te señalo el error de inmediato: las funciones f están vacías y el compilador las ha recortado por completo. Es decir, en realidad no hay ninguna llamada a la función. Tampoco estoy seguro de en qué estado degenerará la función ff y si no acabará siendo inline dentro del bucle for, eliminando así incluso la llamada a la función.

El método virtual, en cambio, no puede ser recortado: siempre es llamado. Como resultado, en un caso el bucle sólo está girando, y en el otro caso la llamada está en el bucle.

En cualquier prueba, primero hay que demostrar su corrección, y sólo después ir a los resultados.

 

Aquí hay uno con una función no vacía:

Archivos adjuntos:
test2.mq4  11 kb
 

Aquí están todas las funciones que son únicas, además, llamadas vía switch, más complejas que un método de clase.

Archivos adjuntos:
test3.mq4  12 kb
 
Integer:

Aquí están todas las funciones que son únicas, además, llamadas vía switch, más complejas que un método de clase.

Qué lío...

¿Has oído hablar de los "inlining"? ¿Qué pasa con el inlining agresivo?

¿Qué suele ocurrir con los cuerpos de las funciones simples y qué hace un buen compilador optimizador con ellos? No estamos en 1995, ¿verdad?

 
MetaDriver:

Me gustaría advertir contra la sobregeneralización. Tal efecto es razonable de esperar en mql, porque utiliza "pseudo-puntos" virtuales - esencialmente manijas que se refieren a la tabla hash interna (oculta) de direcciones reales. Para resolver estos punteros, se necesita una cantidad significativa de tiempo extra, mucho más que el direccionamiento directo de punteros. No he medido, pero es probable que el mismo efecto de "embotellamiento" de punteros se encuentre en los lenguajes dotNET y otras implementaciones similares.

En lenguajes con punteros "reales" no habrá tal efecto, allí el interruptor perderá - cuanto mayor sea la lista de opciones.

Así que la OOP no tiene esencialmente nada que ver...

Sí. Aquí está en do sostenido:)


7550021 (interruptor)
2250004 (OOP)
7325029 (interruptor)
2050015 (OOP)
7550049 (interruptor)
2150005 (OOP)
7575031 (interruptor)
2325009 (OOP)
8025038 (interruptor)
2200004 (OOP)
7150027 (interruptor)
2050014 (OOP)
7375029 (interruptor)
2200005 (OOP)
7550022 (interruptor)
1950003 (OOP)
7100021 (interruptor)
2695083 (OOP)
7360033 (interruptor)
2200008 (OOP)
7825029 (interruptor)
1925010 (OOP)
7325025 (interruptor)
2025006 (OOP)
6850035 (interruptor)
2525014 (OOP)
7750027 (interruptor)
1975007 (OOP)
8195225 (interruptor)
2050004 (OOP)
6950020 (interruptor)
2425006 (OOP)
7275029 (interruptor)
2225015 (OOP)
7050037 (interruptor)
2200007 (OOP)
7375030 (interruptor)

 

Comienza cualquier prueba demostrando que es correcta y que realmente mide lo que dice medir.

Lo que se presenta arriba contiene errores asombrosos y muestra la completa falta de comprensión del autor de los mecanismos de compilación y de cómo funciona el código.

 
Renat:

Comienza cualquier prueba demostrando que es correcta y que realmente mide lo que dice medir.

Lo que se presenta arriba contiene errores asombrosos y muestra la completa falta de comprensión del autor de los mecanismos de compilación y de cómo funciona el código.

¿Por qué debo entender los mecanismos de compilación? ¿Creer que un mal resultado es mejor que uno bueno? Lo que importa es el resultado.
Razón de la queja: