Biblioteca de clases genéricas - errores, descripción, preguntas, características de uso y sugerencias - página 18
Está perdiendo oportunidades comerciales:
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Registro
Entrada
Usted acepta la política del sitio web y las condiciones de uso
Si no tiene cuenta de usuario, regístrese
Ejecuta esto
y conseguí esto.
CArrayList es más rápido que la variante hash. Me metí en las tripas de CArrayList, y hay esto
Ahora me siento engañado. CArrayList resultó ser una envoltura para un array habitual. Pensaba que era una lista normal con punteros Prev/Next, pero se parece a esto
Aparte de los algoritmos de trabajo con estructuras en sí, también está el problema de elegir el contenedor adecuado en función de las particularidades de la tarea.
Así que la interfaz puede ser la misma para diferentes implementaciones. Alguna decepción, no de la interfaz, sino de la implementación específica: el array. Comparado con el hachís, es el cielo y la tierra.
Ahora me siento engañado. CArrayList resultó ser una envoltura para un array normal. Pensé que era una lista normal con punteros Prev/Next, pero aquí está
Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias
Algoritmos, métodos de solución, comparación de resultados
Sergey Dzyublik, 2017.12.10 20:52
Qué clase de DBMS, qué le dices a un hombre que no sabe nada deestructuras de datos.
Si no existe el concepto de ArrayList (vector de C++), de qué podemos hablar aquí.....
Es más su falta de atención aquí...
Leer toda la lista disponible -https://www.mql5.com/ru/docs/standardlibrary/generic
CArrayList es un análogo de std::vector de C++
CLinkedList es probablemente un análogo de std::list de C++
Ejecuta esto
y conseguí esto.
CArrayList es más rápido que la variante hash. Me metí en las tripas de CArrayList, y hay esto
Ahora me siento engañado. CArrayList resultó ser una envoltura para un array habitual. Pensaba que era una lista normal con punteros Prev/Next pero se veía así
Históricamente, la Lista no es una hoja en absoluto - es un array. Así que está bien. Si obtienes una lista en genérico, probablemente se llamará LinkedList o algo así.
Una frustración, no con la interfaz, sino con la implementación específica: el array.
Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading
Biblioteca de clases genéricas - errores, descripción, preguntas, peculiaridades de uso y sugerencias
Sergey Dzyublik, 2017.12.09 01:12
Hay algunas sugerencias de posibles mejoras:
1) En mi humilde opinión, la implementación contiene una elección no del todo correcta de la capacidad - tanto del tamaño inicial 3 como de los subsiguientes al reconstruir la tabla hash.
Sí, es correcto que se elija un número primo para la uniformidad de la distribución.
Sin embargo, la implementación de CPrimeGenerator no cumple las expectativas y contiene omisiones de números primos.
El objetivo de este "generador" es claro: proporcionar un factor de incremento del orden de 1,2 con la generación automática de números primos.
Sin embargo, ¿no es un coeficiente demasiado pequeño? En C++, para los vectores, el coeficiente suele ser de 1,5-2,0, dependiendo de la biblioteca (ya que afecta mucho a la complejidad media de la operación).
La salida podría ser un coeficiente constante seguido del redondeo del número a primo mediante una búsqueda binaria de una lista de números primos.
Y un tamaño inicial de 3 es demasiado pequeño, no vivimos en el siglo pasado.
2) Actualmente la tabla hash se reconstruye (Resize) sólo cuando la capacidad está llena al 100% (todas las m_entradas[] están llenas).
Debido a esto, puede haber una cantidad significativa de colisiones para las claves que no están distribuidas de manera muy uniforme.
Como opción, considere la posibilidad de introducir un factor de llenado, que reduciría el 100% en el límite necesario para la reconstrucción de la tabla hash.
1) El factor de crecimiento del volumen (capacidad) no es igual a 1,2, se utiliza el método CPrimeGenerator::ExpandPrime para calcular el nuevo volumen en CHashMap:
En este método, el tamaño antiguo de la colección se multiplica por dos, luego encontramos el número simple más cercano de la parte superior para el valor resultante y lo devolvemos como el nuevo volumen.
Sobre el valor inicial de la capacidad - estoy de acuerdo, es muy pequeño.
Pero por otro lado siempre hay constructores, donde se puede especificar explícitamente la capacidad inicial:
Así que no veo mucho sentido a cambiar nada aquí.
2) Añadir un parámetro de factor de llenado ayudaría mucho a evitar colisiones en algunos casos. Lo más probable es que se aplique.
1) El coeficiente de capacidad no es igual a 1,2, para calcular el nuevo volumen en CHashMap, se utiliza el método CPrimeGenerator::ExpandPrime:
En este método, el tamaño de la colección antigua se multiplica por dos, luego para el valor resultante encontramos el más cercano del número primo superior y lo devolvemos como el nuevo volumen.
Sobre el valor inicial de la capacidad - estoy de acuerdo, es muy pequeño.
Pero por otro lado siempre hay constructores, donde se puede especificar explícitamente la capacidad inicial:
Por eso no veo ninguna razón para cambiar algo aquí.
2) Añadir el parámetro del factor de llenado ayudará realmente a evitar colisiones en algunos casos. Lo más probable es que se aplique.
Roman, creo que te has hecho una idea equivocada. Ahora algunas clases ni siquiera contienen los métodos más necesarios. ¿Has intentado alguna vez utilizarlos? Por ejemplo, CRedBlackTree, la implementación clásica de un árbol rojo-negro. Un algoritmo bastante bueno pero sin posibilidad de iteración. ¿Qué quieres decir con eso? Hay muchas otras cosas que puede necesitar pero que nadie se ha molestado en implementar por alguna razón. Lo de GetHashCode es horrible. Lo siento, pero no está al nivel de MQ.
Roman, no creo que estés haciendo lo correcto. Ahora algunas clases genéricas ni siquiera contienen los métodos más necesarios. ¿Has intentado utilizarlas? Por ejemplo, CRedBlackTree, la implementación clásica de un árbol rojo-negro. Un algoritmo bastante bueno pero sin posibilidad de iteración. ¿Qué quieres decir con eso? Hay muchas otras cosas que puede necesitar pero que nadie se ha molestado en implementar por alguna razón. Lo de GetHashCode es horrible. Lo siento, pero este no es el nivel de MQ.
Soy muy consciente de la necesidad de los iteradores para todas las colecciones de plantillas de la biblioteca Genric, pero sin la posibilidad de crear clases anidadas y la herencia múltiple de las interfaces, no se pueden implementar correctamente.
Me gustaría escuchar comentarios más específicos sobre GetHashCode.
...
En cuanto a GetHashCode, me gustaría escuchar comentarios más específicos.
Problema
Obviamente, GetHashCode no puede implementarse correctamente en un entorno MQL5 personalizado. Esto se debe a que no se puede acceder a todos los objetos. Y mientras la implementación funciona bien para miembros primitivos como double int, para objetos complejos (clases, estructuras e incluso enumeraciones) el hash se calcula por nombre. Si tenemos miles de CObjects o incluso ENUM_something_that, entonces CHashMap y CHashSet degenerarán en LinkedList:
No podemos evitarlo porque lo único que tenemos a nivel de usuario es el nombre del objeto:
Por lo tanto, los hashes de todos los objetos de tipos complejos son iguales entre sí y este código de búsqueda implica aquí una enumeración completa del array:
De hecho, esto es tan crítico que anula el objetivo de utilizar todos los genéricos en la raíz. La cuestión es que en la mayoría de los casos es necesario asociar o almacenar objetos complejos: enumeraciones, estructuras o clases. Si necesita operar sólo con tipos simples, puede hacerlo con algo más sencillo.
Solución
Obviamente, MQL5 es un lenguaje de programación personalizado de tipo seguro que se ejecuta en una máquina virtual interna. Algo así como la red. Esto significa que el acceso necesario a los objetos sigue existiendo, pero a un nivel más de sistema. Por lo tanto,quizás escribir la función del sistema GetHashCode con el siguiente prototipo:
¿Cómo debería funcionar? En primer lugar, debe ser omnívoro y rápido. Te da una distribución uniforme. Por ejemplo:
Esta función podría estar ubicada en la sección de funciones del sistema. No veo ninguna otra solución.
s.e. Haré otras sugerencias sobre interfaces, herencia múltiple y otras cosas del legado de C++ un poco más tarde.