Errores, fallos, preguntas - página 2667

 
Así que el fallo que he descrito no es de interés para los desarrolladores, vale...
 
Error de MT5 (build 2345) durante mucho tiempo no pude entender por qué el perfilador se ejecuta y funciona, pero no se muestran los resultados en cualquier lugar.
Resulta que el perfilador para el proyecto de script muestra los resultados sólo cuando la optimización está desactivada, si la optimización está activada, todo se ejecuta, funciona, pero sin ningún resultado.
 
Sergey Dzyublik:
Tuve un error de MT5 (build 2345) y no entendía por qué el perfilador se ejecuta y funciona pero no se muestran los resultados.
Resulta que el perfilador para el proyecto de script muestra los resultados sólo cuando la optimización está desactivada, si la optimización está activada entonces todo se ejecutará y funcionará pero sin ningún resultado.

El perfilador no funciona para todos los indicadores (sin optimización). Escribí sobre ello dos veces en el foro, envié el código a los desarrolladores por correo electrónico y no recibí respuesta.

 
He trabajado con el perfilador en MT5 (build 2345),
A grandes rasgos, me preguntaba por qué dos algoritmos que dan el mismo resultado en la ejecución final a diferentes velocidades, una reducción de 1,7x en el modo de optimización.

#include <stl_vector.mqh>

// TickCounts: 850
vector<int>::move test_vector_move_return_assign_by_index(int n){
   vector<int> v(n);
   for(int i = 0; i < n; i++){
      v[i].UNREF  = i;
   }
   return v;
};

// TickCounts: 1450
vector<int>::move test_vector_move_return_push_back(int n){
   vector<int> v;
   // lazy implementation  
   v.reserve(n);                      
   for(int i = 0; i < n; i++){
      v.push_back(i);
   }
   return v;
};


void OnStart()
{
   for(int i = 0; i < 20000; i++){
       vector<int> v_int_move = test_vector_move_return_assign_by_index(1000);
   }
   
   for(int i = 0; i < 20000; i++){
      vector<int> v_int_move = test_vector_move_return_push_back(1000);
   }
}


Como resultado, hemos adquirido experiencia práctica con el perfilador MT5 y hemos detectado una serie de defectos en su funcionamiento.
Como no está claro si los desarrolladores están interesados en esta información, y no se quiere dedicar horas a la localización de errores, sólo se dará una breve información sobre los problemas detectados:

1) No hay manera de comparar las velocidades de los diferentes algoritmos.
Así, un algoritmo que es tres veces más rápido que otros, tanto con la optimización activada como sin ella, puede aparecer como el más lento en el perfilador.
Aparentemente hay algún tipo de sobrecarga del perfilador, que afecta al tiempo de ejecución de los algoritmos, en este caso, no tiene sentido comparar la velocidad de rendimiento de los algoritmos en el perfilador.

2) Valor de recuento incorrecto en la información de herramientas del histograma en la pantalla.
El perfilador dice que la función fue iniciada 80K veces y no 20K veces como se esperaba, al mismo tiempo dentro de la función para diferentes líneas excede el conteo varias veces, para algunas líneas tres veces y para otras dos veces.

3) Valor incorrecto del Tiempo en los tooltips del histograma en la pantalla.
Hay casos en los que el perfilador muestra que el algoritmo entró en la condición el 99,90% de las veces, y en realidad sólo ocurre una vez de 20K pasajes.

 

No es un error, es más bien un comentario.


mt 5 build 2340.

Ayer cuando abrí el Directorio de Datos no me di cuenta de que la carpeta de Indicadores se había movido a la carpeta de Expertos. Luego deshabilité el mt5 y lo habilité hoy, los indicadores también se pueden usar desde el Navegador como si nada. Sin embargo, si volvía a abrir la Carpeta de Datos, había una carpeta de Indicadores vacía y si ya había colocado algún indicador allí, no aparecía en el Navegador. No aparecerá en el Navegador. La devolución de la carpeta de Indicadores de nuevo a MQL5\NIndicadores resuelve el problema.

 

MT5 (build 2347) ¿Por qué una sobrecarga tan grande cuando se añade un elemento a la vez a una matriz utilizando ArrayResize, si la memoria se ha reservado para ellos de antemano?

#define  K 1000
#define  M (1000 * K)

#define    SpeedTest(test_count,msg,EX)        {uint mss=GetTickCount(); ulong count=test_count;for(ulong ii=0;ii<count&&!_StopFlag;ii++){EX;} \
                                              printf("%-60s: loops=%i ms=%u",msg,count,GetTickCount()-mss);}
                                              
class A{
public:
   int data;
};

struct B{
   int data;
};

template<typename T>
void test1(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
      for(int i = 1; i <= array_size; i++){
         ArrayResize(class_array, array_size);
      }
   }
   )
};

template<typename T>
void test2(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with reserved memory",
   {
      T class_array[];
      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 2; i <= array_size; i++){
         ArrayResize(class_array, i);
      }
   }
   )
};

void OnStart()
{
  const int test_count = 5*K;
  const int array_size = 5*K;  
  
  test1<int>(test_count, array_size);            // Avg time: 100
  test2<int>(test_count, array_size);            // Avg time: 190
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  test1<int>(test_count, array_size);
  test2<int>(test_count, array_size);
  
printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  test1<A>(test_count, array_size);              // Avg time: 810
  test2<A>(test_count, array_size);              // Avg time: 1460
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  test1<A>(test_count, array_size);
  test2<A>(test_count, array_size);
  
printf("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
  test1<B>(test_count, array_size);              // Avg time: 110
  test2<B>(test_count, array_size);              // Avg time: 770
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
  test1<B>(test_count, array_size);
  test2<B>(test_count, array_size);
}

Por favor, considere la posibilidad de mejorar el algoritmo de reserva interna con ArrayResize.

Por ejemplo, para las clases podemos suponer que realizan algún tipo de "registro interno en listas" además de la llamada al constructor.
Y en el marco de la reserva con ArrayResize, además de la asignación directa de memoria, se puede intentar optimizar el proceso:
- tomar datos del elemento adyacente creado (por ejemplo, puntero a una tabla de funciones virtuales);
- preejecutar o reservar espacio para la "inscripción interna" de las clases que aún no han sido creadas;

 
Sergey Dzyublik:

MT5 (build 2347) ¿Por qué una sobrecarga tan grande cuando se añade un elemento a la vez a una matriz utilizando ArrayResize, si la memoria se ha reservado para ellos de antemano?

Incluso eso no ayuda.

      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 0; i < array_size; i++){
//         ArrayResize(class_array, i);
         ArrayResize(class_array, i, array_size - 1);

No tiene ningún sentido. En lugar de acelerarse, se ralentiza.


ZZ Es extraño, el resultado de ejecutar el ejemplo de la Documentación es cero.

--- Test Fast: ArrayResize(arr,100000,100000)
1. ArraySize(arr)=100000 Time=0 ms
2. ArraySize(arr)=200000 Time=0 ms
3. ArraySize(arr)=300000 Time=0 ms
---- Test Slow: ArrayResize(slow,100000)
1. ArraySize(slow)=100000 Time=0 ms
2. ArraySize(slow)=200000 Time=0 ms
Документация по MQL5: Операции с массивами / ArrayResize
Документация по MQL5: Операции с массивами / ArrayResize
  • www.mql5.com
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Если ArrayResize() применена к статическому массиву, таймсерии или индикаторному буферу, то размер массива остается прежним – такие массивы не могут быть...
 
Sergey Dzyublik :
Funciona con el perfilador en MT5 (build 2345),
A grandes rasgos, me preguntaba por qué dos algoritmos, que dan el mismo resultado al final, funcionan con diferente velocidad, una reducción de 1,7 veces en el modo de optimización.


...

Desgraciadamente, este perfil de tiempo largo es inútil para cualquier proyecto importante. Ya intenté informar de esto, pero no hubo interés por parte de los desarrolladores.
 
Sergey Dzyublik :

MT5 (build 2347) ¿Por qué una sobrecarga tan grande cuando se añade un elemento a la vez a una matriz utilizando ArrayResize, si la memoria se ha reservado para ellos de antemano?

Si quieres comparar, debería serlo:

 void test1 ( const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
       for ( int i = 0 ; i < array_size; i++){
         ArrayResize (class_array,  i );
      }
   }
   )
 
Alain Verleyen:

Si quieres comparar, debería serlo:

Por mi parte, la comparación era lo que debía ser.
Sé cuántos elementos se colocarán en el array y en lugar de crearlos todos a la vez reservo memoria para los no creados.
El problema es que si reservo la memoria y creo los elementos del array uno a uno, se tarda muchas veces más que creándolos todos a la vez.
Así que para las estructuras es 7 veces más lento.
Y es dos veces más lento para los tipos de datos class e int.

Esta es una diferencia muy grande, que creo que los desarrolladores pueden eliminar si lo desean.