El esplendor y la pobreza de la OLP - página 5

 
meat:

Aquí, según entiendo, el índice se define a través de una búsqueda binaria?

No, acceso directo como en un array.

__________

Tal vez me equivoque, lo pensaré.

En general, nadie te impide crear un array para todo el tamaño del tipo y obtener un acceso constante. (el interruptor sólo funciona con los tipos integrales).

En el caso que describes, es más conveniente introducir una enumeración.

 
TheXpert:

No, acceso directo como en un array.

__________

Tal vez exageré, lo pensaré de nuevo.

En realidad nadie te impide crear un array para todo el tamaño del tipo y obtener un acceso constante. (El interruptor sólo funciona con los tipos integrales).

En el caso que has descrito, sería más conveniente crear una enumeración.

¿Para todo el valor del tipo? ¡No puede ser! En este caso se necesitarán 16 Gb de memoria (para un array de tipo int). ¿Y qué sentido tiene tomar el valor completo? Bastará con calcular la diferencia entre el valor máximo y el mínimo. Pero, de todas formas, este es un caso discutible, porque cuando los valores son grandes, hay que negociar primero con el usuario cuánta memoria está dispuesto a asignar al programa. Por eso sólo es adecuado para valores de clave pequeños (o más bien para una diferencia pequeña entre el máximo y el mínimo). Esto deja sólo la búsqueda binaria.

 
meat:

Esto deja sólo la búsqueda binaria.

No, no es necesario. En resumen, si necesitas mapear un número a un número, necesitas una búsqueda binaria. Si trabajar con un número y mapear el número a un número es suficiente, entonces necesitas una búsqueda constante.

Entiendo lo de la memoria )), por eso escribí que me pasé.

 

siempre hay lugar para la pregunta - ¿Por qué? compare el gráfico de dispersión en línea y en el probador. El probador no tiene nada que ver con la realidad...

tol64:

¿Ha dado ya una explicación más detallada (prueba) en alguna parte?

Tienes que respaldar tus afirmaciones con pruebas, de lo contrario ni siquiera lo mirarás. ;)

 
C-4:
Chicos, leed la documentación del interruptor. Un buen conmutador es una transición conmutada cuyo rendimiento no depende del número de opciones. 1 elección, 100 o 1000 - su tasa de transición será constante.
Wah gracias, buena referencia, lo leí con gusto y beneficio.
 
dimeon:

siempre hay lugar para la pregunta - ¿Por qué? compare el gráfico de dispersión en línea y en el probador. El probador no tiene nada que ver con la realidad...

Para llamar la atención. Abre un nuevo hilo y cubre tu pregunta con más detalle. Muestra cómo en el real y cómo en el probador. Ofrezca su solución a este problema. De lo contrario, se quedará "sin posibilidad y sin opciones". )
 
Vinin:

Las pruebas vendrán del otro lado. O de nuevo sólo palabras.

En general, sólo me interesan los hechos.

Aunque ya sé que la OOP es más lenta, pero proporciona comodidades bastante concretas.

Como prometí, expongo los resultados de los perfiles de un proyecto. (Por favor, discúlpeme, pero algunas funciones están tachadas, porque el código no es para el público en general).

Para empezar diré que se trata de un verdadero proyecto OOP, con una fuerte transformación de los datos de origen. La idea de utilizar la POO en ella se lleva al absoluto. Por ejemplo, no utiliza variables globales, arrays, funciones fuera de las clases en absoluto - porque no son lo suficientemente OOP. Para que funcione, necesitamos el historial de pedidos y operaciones realizadas durante todo el periodo. El análisis de 6014 operaciones y 6.599 órdenes sólo requiere 3,1 segundos, es decir, 0,25 milisegundos por transacción, y la memoria RAM para desplegar todas las operaciones, órdenes y posiciones requiere unos 13 MB, es decir, una media de 1 kilobyte por transacción. - Creo que es un resultado muy bueno para una aplicación OOP:

2014.07.07 12:44:33.464 TestMA (AUDCAD,H1) Estamos empezando. El análisis de las operaciones del historial (6014) y de los pedidos (6599) se ha completado en 3,104 segundos. 13MB de RAM utilizados.

Pero echemos un vistazo a la estructura del tiempo que se tarda en inicializar la aplicación:

Vemos que la mayor parte del tiempo se dedica a llamar a la función AddNewDeal. Esta es una función compuesta y el trabajo real se delega en RecalcValues (57%). A su vez, consta de funciones del sistema como HistoryOrderGetInteger:

Obsérvese que los tiempos de llamada de estas funciones son aproximadamente iguales.

Tenga en cuenta que este es el final de todo el transportador de funciones. Antes de llegar a estos cálculos hay que pasar otra docena de métodos OOP intermedios, y algunos de ellos también son virtuales. Pero su tiempo de ejecución es insignificante y en el perfilador están en la segunda mitad de la lista.

Al tratarse de una aplicación 100% OOP, me resulta muy fácil hacer un seguimiento de las secciones de código en las que el tiempo es crítico, y puedo encontrar de forma muy eficaz nuevas formas de mejorar el rendimiento. Ya sé que la parte restante (43%) está compuesta en un 80-90% por llamadas a CArray.Resize(). Hay algunos lugares en los que el código no está optimizado y la repartición de arrays se produce con más frecuencia de la necesaria. Podría reescribir fácilmente estos módulos OOP y mejorar el rendimiento en un 25%-30%. Sin la POO sería más difícil de hacer porque cada función está potencialmente involucrada en un número infinito de interrelaciones y se hace mucho más difícil calcular las consecuencias de los cambios en dicha función.

El resultado es que incluso un complejo proyecto OOP puede ser llevado al límite de rendimiento de las funciones básicas del sistema. Pero sin la POO será más difícil lograr esa productividad, porque habrá tantas funciones que tarde o temprano se cometerá un error: se harán llamadas innecesarias o gemelos no optimizados, o implementaciones demasiado complejas y engorrosas.

 
dimeon:

siempre hay lugar para la pregunta - ¿Por qué? compare el gráfico de dispersión en línea y en el probador. En el probador no tiene nada que ver con la realidad...

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

La gloria y la miseria de la OOP

tol64, 2014.07.07 09:12

Para llamar la atención. Abre un nuevo tema y cubre tu pregunta con más detalle. Muestra cómo es en la vida real y cómo es en el probador. Proponga su propia solución a este problema. De lo contrario, se quedará "sin posibilidad y sin opciones". )

+++

adimeon - Abre un hilo, aprenderás muchos argumentos de por qué no se puede y por qué se debe.

 
C-4:

Tal y como prometí, voy a publicar los resultados del perfil de un proyecto. (Sin faltar al respeto, pero algunas funciones están enmascaradas ya que el código no es para el público en general).

...

¿Qué sentido tiene todo esto? No has citado los códigos de tus funciones (a no ser que cuentes algún fragmento desgarrado). Entonces, ¿qué hay que discutir? Este hilo trata específicamente de comparar el rendimiento de la POO y la programación procedimental. Y el hecho de que tus funciones secretas supuestamente realicen algún trabajo, deleguen algo en algún lugar, tomen algún tiempo, y tú manejes todo esto con maestría - por supuesto, estamos increíblemente felices por ti, pero de qué servirá esta información, si no vemos los códigos.

 
meat:

¿Qué sentido tiene todo esto? No has citado los códigos de tus funciones (a no ser que cuentes algún fragmento desgarrado). Entonces, ¿qué hay que discutir? El tema aquí es específicamente sobre la comparación del rendimiento de la POO y la programación procedimental. Y el hecho de que tus funciones secretas supuestamente realicen algún trabajo, deleguen algo en algún lugar, tomen algo de tiempo, y tú manejes magistralmente todo esto - por supuesto, estamos increíblemente felices por ti, pero de qué servirá esta información, si no vemos los códigos.

Demostró que la llamada directa o la llamada virtual no tienen ningún efecto en los proyectos reales.

Mediante el ejemplo de perfilado de un proyecto real de POO mostraré que su rendimiento en el límite tiende al rendimiento de las llamadas a funciones del sistema

La gran mayoría de los costes se producen en la llamada a las funciones del sistema, donde pasa la mayor parte del tiempo de los programas MQL. Los costes de organización de las llamadas son insignificantes en comparación con la carga útil.