Discusión sobre el artículo "Recetas de MQL5 - implementamos el array asociativo o el diccionario para el acceso rápido a los datos"
Artículo publicado Recetas MQL5 - Implementar un array asociativo o diccionario para un acceso rápido a los datos:
Autor: Vasiliy Sokolov
Buen trabajo, ¡felicitaciones al autor! Esto es algo que MQ debería haber incluido en \MQL5\IncludeArrays hace mucho tiempo, espero que se incluya en la librería en las próximas versiones. Por cierto, todo funciona bien en MQL4 también, aquí están las mediciones de la primera prueba. ¿Entiendo que es imposible incluir tipos de datos simples en lugar de *CObject debido a la falta de punteros completos? ¿O hay alguna forma de evitarlo?
2015.03.23 13:25:54.617 TestDict EURUSD,M1: 1000000 elements. Add: 1373; Get: 218 2015.03.23 13:25:52.644 TestDict EURUSD,M1: 950000 elements. Add: 1216; Get: 219 2015.03.23 13:25:50.833 TestDict EURUSD,M1: 900000 elements. Add: 1217; Get: 218 2015.03.23 13:25:49.069 TestDict EURUSD,M1: 850000 elements. Add: 1154; Get: 187 2015.03.23 13:25:47.424 TestDict EURUSD,M1: 800000 elements. Add: 1092; Get: 187 2015.03.23 13:25:45.844 TestDict EURUSD,M1: 750000 elements. Add: 1061; Get: 171 2015.03.23 13:25:44.320 TestDict EURUSD,M1: 700000 elements. Add: 1107; Get: 156 2015.03.23 13:25:42.761 TestDict EURUSD,M1: 650000 elements. Add: 1045; Get: 140 2015.03.23 13:25:41.304 TestDict EURUSD,M1: 600000 elements. Add: 1014; Get: 156 2015.03.23 13:25:39.915 TestDict EURUSD,M1: 550000 elements. Add: 920; Get: 125 2015.03.23 13:25:38.665 TestDict EURUSD,M1: 500000 elements. Add: 702; Get: 109 2015.03.23 13:25:37.693 TestDict EURUSD,M1: 450000 elements. Add: 593; Get: 93 2015.03.23 13:25:36.836 TestDict EURUSD,M1: 400000 elements. Add: 577; Get: 78 2015.03.23 13:25:36.025 TestDict EURUSD,M1: 350000 elements. Add: 561; Get: 78 2015.03.23 13:25:35.247 TestDict EURUSD,M1: 300000 elements. Add: 515; Get: 78 2015.03.23 13:25:34.557 TestDict EURUSD,M1: 250000 elements. Add: 343; Get: 63 2015.03.23 13:25:34.063 TestDict EURUSD,M1: 200000 elements. Add: 312; Get: 47 2015.03.23 13:25:33.632 TestDict EURUSD,M1: 150000 elements. Add: 281; Get: 31 2015.03.23 13:25:33.264 TestDict EURUSD,M1: 100000 elements. Add: 171; Get: 16 2015.03.23 13:25:33.038 TestDict EURUSD,M1: 50000 elements. Add: 47; Get: 16
Buen trabajo, ¡felicitaciones al autor! Esto es algo que MQ debería haber incluido en MQL5/Include/ Arrays hace mucho tiempo, espero que se incluya en la librería en las próximas versiones. Por cierto, todo funciona bien en MQL4 también, aquí están las medidas de la primera prueba. ¿Entiendo que es imposible incluir tipos de datos simples en lugar de *CObject debido a la falta de punteros completos? ¿O hay alguna forma de hacerlo funcionar?
Funcionará. Con la ayuda del mecanismo boxing/unboxing y las plantillas. La idea es que cada tipo base se empaquete en un contenedor KeyValuePairBase. El desempaquetado y la devolución del tipo correspondiente se realiza mediante funciones internas del tipo GetObjectByKey:
template<typename Type, typename T>
Type GetObjectByKey(T key);
Es importante destacar que trabajar con tipos base no proporcionará ninguna ventaja de rendimiento, pero será mucho más cómodo.
Ahora intenté crear un CDictionaryBase almacenando uno de los tipos básicos de MQL en lugar de CObject en base a plantillas. Desafortunadamente, no funcionó, las funciones no permiten devolver un tipo de plantilla. Es una lástima:
//+------------------------------------------------------------------+ //|TestDictBase.mq5 //|Derechos de autor 2015, Vasiliy Sokolov. | //|http://www.mql5.com //+------------------------------------------------------------------+ #property copyright "Copyright 2015, Vasiliy Sokolov." #property link "http://www.mql5.com" #property version "1.00" #include <Dictionary.mqh> #include <DictionaryBase.mqh> //+------------------------------------------------------------------+ //| Función de inicio del programa de script| //+------------------------------------------------------------------+ void OnStart() { //--- CDictionaryBase base; base.AddValue("Pi", 3.14159); double pi = (double)base.GetValueByKey("Pi"); printf(DoubleToString(pi, 5)); //base.AddObject( } //+------------------------------------------------------------------+
could not deduce template argument #1 TestDictBase.mq5 19 29 could not deduce template argument #0 DictionaryBase.mqh 404 25 possible loss of data due to type conversion DictionaryBase.mqh 133 10 possible loss of data due to type conversion DictionaryBase.mqh 135 10 possible loss of data due to type conversion DictionaryBase.mqh 137 10 ...
//+------------------------------------------------------------------+ //| Devuelve el objeto por clave.| //+------------------------------------------------------------------+ template<typename T, typename C> C CDictionaryBase::GetValueByKey(T key) { if(!ContainsKey(key)) return NULL; return m_current_kvp.GetValue(); }
Una pena.
Así que, para cada tipo base tendremos que crear un contenedor base, o simplemente crear contenedores de tipos base: CDouble, CLong, CInt, etc.
Ahora intenté crear un CDictionaryBase almacenando uno de los tipos básicos de MQL en lugar de CObject en base a plantillas. Desafortunadamente no pude hacerlo, las funciones no permiten devolver un tipo de plantilla.
Lo hacen. Pero el tipo del valor devuelto no se puede deducir automáticamente, que en realidad está escrito por el compilador.
Usted puede utilizar una pequeña muleta en forma de un pseudo-parámetro.
template<typename T, typename C> C CDictionaryBase::GetValueByKey(T key, C) { if(!ContainsKey(key)) return NULL; return m_current_kvp.GetValue(); }
Lo hacen. Pero no se puede deducir automáticamente el tipo del valor devuelto, que es lo que realmente escribe el compilador.
Puedes utilizar una pequeña muleta en forma de pseudoparámetro.
¿Dónde está la muleta real?
Se ha añadido un segundo parámetro
¿Has probado a comparar el rendimiento? ¿A partir de qué tamaño de datos comienza la ventaja sobre la búsqueda binaria en una matriz de cadenas ordenada?
No he hecho pruebas exactas, pero según mis observaciones la ventaja de velocidad empieza a aparecer a partir de decenas de miles de elementos. Es decir, en tareas cotidianas con 100-10 000 elementos no se puede obtener una ganancia de rendimiento.
Otra cosa es importante aquí, a saber, la conveniencia de trabajar con el contenedor. No es necesario escribir métodos adicionales para buscar elementos. Muchas tareas cotidianas con diccionarios se vuelven mucho más fáciles de implementar. No necesitas crear un elemento para buscar un índice, luego recuperar el necesario por el índice correspondiente, etc., etc.
s.s. Aunque aquí pensé que el rendimiento debería medirse como el tiempo total para insertar elementos y buscarlos. Y si buscar elementos ordenados en CArrayObj es una operación bastante rápida, entonces la inserción es un verdadero problema. Dado que la búsqueda rápida requiere ordenación, no podemos deshacernos de posibles inserciones, y esto ralentizará significativamente el rendimiento.
Muy interesante y está claro que el diccionario es muy útil y fácil de usar organizador de datos.
Gracias por compartirlo.

- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Artículo publicado Recetas de MQL5 - implementamos el array asociativo o el diccionario para el acceso rápido a los datos:
En este artículo se describe un algoritmo especial que permite acceder de manera eficaz a los elementos usando su clave única. Como clave se puede utilizar cualquier tipo básico de datos, por ejemplo, las cadenas o variables de números enteros. Este contenedor de datos suelen llamarlo el diccionario o array asociativo. La solución de muchas tareas con su ayuda resulta más simple y eficaz.
Este artículo describe una clase cómoda para almacenar la información: array asociativo o diccionario. Gracias a esta clase se puede acceder a la información por su clave.
El array asociativo recuerda un array común, pero en vez del índice utiliza una clave única, por ejemplo, la enumeración ENUM_TIMEFRAMES o cualquier texto. No importa qué clave es, lo importante es que esta clave sea única. Este algoritmo de almacenamiento de datos simplifica considerablemente muchos aspectos de programación.
Por ejemplo, la función para recibir el código del error y mostrar el equivalente textual de este error podría tener el siguiente aspecto:
Más tarde analizaremos la específica de este código.
Antes de pasar directamente a la descripción de la lógica interna del array asociativo, vamos a considerar con detalles dos modos principales de almacenamiento de datos: se trata de los arrays y de las listas. Nuestro diccionario va a basarse precisamente en estos dos tipos de datos, por eso tenemos que comprender muy bien las características específicas de su funcionamiento. El capítulo 1 está destinado a la descripción de los tipos de datos. El capítulo 2 describe el array asociativo y el modo de trabajo con él.
Autor: Vasiliy Sokolov