Borrar una matriz de elementos definidos - página 29

 
Sergey Dzyublik:
Esencialmente estás usando una estructura de datos HashSet estática con un array inicial de datos para resolver las colisiones.
Pero la puesta en práctica es simplemente reveladora...

En lugar de llamar a la función ("FindValueInSortArray") con 100-500 parámetros innecesarios, normalmente se utiliza la clase donde estos parámetros actúan como campos de la clase (ganancia en el paso de los parámetros, si el compilador no adivinó para hacer inline implícito).
Si es necesario utilizar un par de arrays del mismo tamaño y con un mismo propósito de uso ( int p1[]; int p2[];), normalmente se utiliza un array de estructura (ventaja de acceso al índice, menor posibilidad de pérdida de caché).

Sí, lo sé. Estoy de acuerdo, yo mismo tengo miedo de mi propia implementación. Pero mi objetivo es el algoritmo, no la implementación. Como se dice, "montado de rodillas" (alrededor de una hora y media), para comprobar la corrección y la velocidad del algoritmo. Recordemos que en este hilo se discute (y cito) "la forma más rápida de vaciar un array de valores basura".

Aunque tengo muchas quejas sobre mi propio algoritmo, porque está lejos de ser universal. Puedo ver formas de mejorar el algoritmo, pero el código se volverá mucho más complejo. Una pena lo de la hora.

ZZY HashSet escuchó por primera vez, porque no soy fuerte en la teoría. Soy muy consciente de que no he inventado nada nuevo y que todo se inventó antes que yo. :)) La ventaja de este algoritmo es evidente cuando el conjunto de elementos a eliminar tiene una distribución uniforme. Si la distribución es muy diferente de la uniforme, esta implementación puede ser inferior en velocidad a otras que ya existen en esta rama.

 
Taras Slobodyanik:

ha cambiado el cálculo del importe a CRC32 )

Gracias. Por supuesto que es más correcto.

Pero por lo que tengo entendido, el cambio a CRC32 no reveló ningún error. :)

 

Déjenme decirles que estoy personalmente impresionado por las capacidades de los ordenadores modernos y de MQL5 en particular.

Al fin y al cabo, sólo se tarda 1/40 segundos (!!!) en buscar unos mil valores diferentes en una matriz de un millón de elementos, borrarlos (unas 100.000 celdas) y volver a empaquetar la matriz limpia.

 
optimizado
Archivos adjuntos:
 
nicholi shen :

Todo es brillantemente sencillo. :))

Pero, sin embargo, este algoritmo consume memoria de forma incontrolada.

Así, por ejemplo, si se sustituye

arr[i]= rand ()% 10000 ;
....
Value2[i]= rand ()% 10000 ;

con .

arr[i]= rand ()* rand ();
....
Value2[i]= rand ()* rand ();

la situación es completamente diferente:

2018.11 . 19 23 : 25 : 57.593 ArrayDeleteValue21 (NZDUSD,D1)  вариант nicholi shen: Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  603551 микросекунд
2018.11 . 19 23 : 25 : 57.980 ArrayDeleteValue21 (NZDUSD,D1)  вариант Nikitin     : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -  383847 микросекунд
2018.11 . 19 23 : 25 : 58.043 ArrayDeleteValue21 (NZDUSD,D1)  вариант fan9        : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   61414 микросекунд
2018.11 . 19 23 : 25 : 58.074 ArrayDeleteValue21 (NZDUSD,D1)  вариант Semko       : Контрольная сумма = 3902843984.813025 ; элементов - 999983 ; время выполнения -   28430 микросекунд
Archivos adjuntos:
 
Añadido ArrayDeleteValue a un par de personas más en el proyecto, los derechos de edición. A quien no he visto antes.
 
Nikolai Semko:

Gracias. Este es sin duda el camino correcto.

Pero por lo que tengo entendido, el cambio a CRC32 no reveló ningún error. :)

Sí, pero ahora los que han visto con sus propios ojos el resultado de un solo algoritmo, pueden asegurarse de que otros obtengan el mismo resultado)

 
Por favor, escriba sobre el tema. No hay que decir palabrotas ni insultos. Gracias.
 
nicholi shen:

No es una mala idea, pero si hay valores negativos en un array o vector, obtendrá un error de array fuera de rango

Además, el tamaño de un array con banderas de filtrado puede llegar a2 147 483 647, lo que es demasiado

Por supuesto, se puede reducir el tamaño en 32 veces sustituyendo la configuración de 32 variables BOOL por una máscara de bits como ésta:

int array_filter(int &a[],const int &b[]) //nicholishen
{
   int e=ArraySize(a);
   int c[];
   int d =b[ArrayMaximum(b)]+1;
   ArrayResize(c, b[ArrayMaximum(b)]/32 + 1);
   ArrayInitialize(c, 0);
   int i=0;
   int ii=0;
   while(i<ArraySize(b))
   {     
     ii=b[i]/32;
     c[ii]|=(1<<(b[i]-(ii*32)));
     i++; 
   } 
   
   int g=0, h=0, f=0;
   for(g=0; g<e; g++){
      f = a[g];
      ii=f/32;
      if(f >= d || !(c[ii] & (1<<(f-(ii*32)))) )
      {
         a[h]=f;
         h++;
      }
   }
   return ArrayResize(a, h);
}


pero seguiría siendo demasiado grande y la velocidad se reduciría a la mitad.

 
Nikolai Semko:

Todo es brillantemente sencillo. :))

Pero, sin embargo, este algoritmo consume memoria de forma incontrolada.

Así, por ejemplo, si se sustituye

con .

la situación es muy diferente:

Su versión también es buena, pero lamentablemente también tiene un punto débil. En condiciones "domésticas", es decir, matrices pequeñas de tamaño ~100 y vector pequeño ~5-10

su algoritmo será más lento que todos los presentados aquí, aunque la diferencia en microsegundos es tan insignificante que probablemente no importe, pero en matrices más grandes es el mejor.

P.S Creo, que la función debe ser universal, es necesario combinar en ella algunos algoritmos diferentes recogidos según los datos de entrada.