Borrar una matriz de elementos definidos - página 11

 
Nikolai Semko:

¡Bravo! Después de corregir un par de errores, me has bajado del pedestal incluso sin usar ArrayCopy. Jaque mate. :))

Probablemente valga la pena cambiar
for(;;)

a

while(true)

Sigue saliendo por la pausa

P.D. Sólo por diversión, ejecuté una copia directa en toda la matriz.
template<typename T>
int arrayFilter(T &data[],const T value)
  {
     int s, _s = s = ArraySize(data);
     bool result = false;
     
     for(int i=0, j=0; i<_s; i++)
     {
          if( data[i] == value )
          {
               result = true;
               s--;
               continue;
          }
          if( result )
               data[j] = data[i];
          j++;
     }
     
     if(s < _s)
          ArrayResize(data, s);
     
     return s;
  }
 
Konstantin Nikitin:
Probablemente valga la pena cambiar

a

Sigue saliendo por la pausa

No hay ninguna diferencia. De los bucles infinitos, me gusta más el for porque es más corto y el true no confunde a los novatos.
 
Un gran dolor de cabeza para los desarrolladores del optimizador MT5/ME (builds 1945).
Terminal Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Memoria: 5276 / 16250 Mb


Por qué el código:
arr[j++] = arr[i];

Funciona más lento que:
arr[j] = arr[i];
j++;



Si se presenta a este concurso sin reglas, deberá copiar el código del "líder" (actualmente Kuznetsov) y modificarlo de acuerdo con el comportamiento del sistema descrito anteriormente.
Esto lleva a una ganancia estable de unos 20 mseg desde el tiempo de ejecución inicial de 740 mseg:

template <typename T>
int arrayFilter_ALXIMIKS(T &arr[], const T x)  // вариант ALXIMIKS
{
        int i=0;
        int j=ArraySize(arr)-1;
        for(;;) {
                while(arr[i]!=x && i<j) i++;
                while(arr[j]==x && i<j) j--;
                if (i<j) {
                        arr[i]=arr[j];
                        i++;
                        j--;
                } else break;
        }
        ArrayResize(arr,j);
        return j;
}
 

Por cierto, tengo curiosidad por saber cómo cambiarán los resultados si la matriz original es una serie. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
Si tomamos este concurso sin reglas, copiamos el código del "líder" (actualmente Kuznetsov) y lo modificamos según el comportamiento anterior del sistema.

Obtenemos una ganancia estable de unos 20 ms respecto al tiempo de ejecución original de 740 ms:

Vale la pena añadir. Si no te importa la secuencia de los elementos del array. Entonces sí, es una variante excelente. Si es importante mantener la coherencia, entonces se necesita algo más.

 

Ya que estamos, esta es mi versión:

int SokolovDelRetry(int &array[], const int val)
{
   int total = ArraySize(array);
   int in = -1, count = 0, diff = 0;
   for(int i = 0; i < total; i++)
   {
      diff++;
      if(array[i] == val)
      {
         diff--;
         if(in != -1)
         {
            if(diff>0)
            {
               ArrayCopy(array, array, in, i-diff, diff);
               in = in + diff;
               diff = 0;
            }
            count++;
         }
         else
         {
            in = i;
            diff = 0;
            count++;
         }
      }
   }
   if(diff > 0)
      ArrayCopy(array, array, in, total - diff, diff);
   ArrayResize(array, total - count);
   return total - count;
}

resultados:

2018.11.14 16:20:15.293 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Pastushak: Контрольная сумма = 495345526; элементов - 998956; время выполнения = 89383 микросекунд
2018.11.14 16:20:15.313 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Korotky:   Контрольная сумма = 495345526; элементов - 998956; время выполнения = 18148 микросекунд
2018.11.14 16:20:15.337 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Fedoseev:  Контрольная сумма = 495345526; элементов - 998956; время выполнения = 15637 микросекунд
2018.11.14 16:20:15.347 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Semko:     Контрольная сумма = 495345526; элементов - 998956; время выполнения = 4626 микросекунд
2018.11.14 16:20:15.367 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Pavlov:    Контрольная сумма = 495345526; элементов - 998956; время выполнения = 16976 микросекунд
2018.11.14 16:20:15.407 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Nikitin:   Контрольная сумма = 495345526; элементов - 997945; время выполнения = 27381 микросекунд
2018.11.14 16:20:15.427 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Vladimir:  Контрольная сумма = 495345526; элементов - 998956; время выполнения = 16178 микросекунд
2018.11.14 16:20:15.457 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Peter:     Контрольная сумма = 495345526; элементов - 998956; время выполнения = 19618 микросекунд
2018.11.14 16:20:15.477 ArrayDeleteValue__6 (FORTS-USDRUB,H1)   вариант Sokolov:  Контрольная сумма = 495345526; элементов - 998956; время выполнения = 11058 микросекунд

S.S. En principio, se ha alcanzado el límite de velocidad. El siguiente paso es sólo la micro-optimización y juguetear con el bucle for:

Creo que el resultado de Nikolai es un hábil uso de esas microoptimizaciones.

Archivos adjuntos:
 
Vladimir Pastushak:

Hay un array que contiene un conjunto de datos de tipo 1,2,3,6,9,5,6,3,25,6,8,7,4 hay que eliminar por ejemplo los valores 3 y obtener el mismo array sin 3 y espacios vacíos en la salida...

Estoy buscando la forma más rápida de borrar un array de valores innecesarios...

Me viene a la mente el siguiente ejemplo

¿Quizás haya una forma más barata y rápida?

Vladimir, ¿por qué es necesario?
Según tengo entendido, hay que hacerlo con el buffer del indicador. Pero, ¿no sería más lógico sustituir los valores vacíos y/o "innecesarios" por el valor anterior o, por ejemplo, la media aritmética de los valores extremos? Entonces será mucho más rápido y la dimensión del array seguirá siendo la misma.

 
Nikolai Semko:

Vladimir, ¿por qué es necesario?
Según tengo entendido, hay que hacerlo con el buffer del indicador. Pero, ¿no sería más lógico sustituir los valores vacíos y/o "innecesarios" por el valor anterior o, por ejemplo, la media aritmética de los valores extremos? Entonces será mucho más rápido y la dimensión del array seguirá siendo la misma.

Esto es necesario para mostrar información, una gran cantidad de información y hacer cálculos posteriores basados en ella. Una función de este tipo es necesaria para limpiar el array de datos irrelevantes. Y lo más importante, ¡debe funcionar muy rápido! Mi analógico es inferior en cuanto a velocidad, provoca congelaciones al mostrar la información.

 
Nikolai Semko:

Vladimir, ¿por qué es necesario?
Según tengo entendido, hay que hacerlo con tampón indicador. Pero ¿no sería más lógico sustituir los valores vacíos y/o "innecesarios" por el valor anterior o la media aritmética de los valores extremos, por ejemplo? Entonces será mucho más rápido y la dimensión del array seguirá siendo la misma.

Cuando hay varios EAs con un gran número de posiciones/órdenes abiertas en mql4, en mi opinión, es más fácil mantener el array con las entradas y comprobar si la orden está cerrada recorriendo el array en lugar de probar todas las posiciones abiertas con la comprobación del símbolo y el mago. Por lo tanto, si la orden está cerrada, debe ser "tachada" de la matriz. En estos casos, solía copiar el array "en sí mismo" y reducir el tamaño del array en uno. Eso fue sugerido por Vasiliy Sokolov, muchas gracias, sabré que no es la opción más difícil, ya que nunca pensé en la velocidad. El porqué de la tarea de eliminar varios elementos iguales es otra cuestión...

ps Mientras escribía esto, la respuesta ya está ahí. Así que la pregunta también es errónea... ))))))
 
Alexey Viktorov:

Cuando hay varios EAs con un gran número de posiciones/órdenes abiertas en mql4, en mi opinión, es más fácil mantener el array con las entradas y comprobar si la orden está cerrada recorriendo el array en lugar de probar todas las posiciones abiertas con la comprobación del símbolo y el mago. Por lo tanto, si la orden está cerrada, debe ser "tachada" de la matriz. En estos casos, solía copiar el array "en sí mismo" y reducir el tamaño del array en uno. Eso fue sugerido por Vasiliy Sokolov, muchas gracias, sabré que no es la opción más difícil, ya que nunca pensé en la velocidad. El porqué de la tarea de eliminar varios elementos iguales es otra cuestión...

ps Mientras escribía, la respuesta ya está ahí. Resulta que la pregunta también es errónea... ))))))

A grandes rasgos, me lo imaginé entonces.

Si tenemos un array de órdenes, el orden no es importante, por lo que es más razonable utilizar la variante de Kuznetsov con el llenado de "huecos" con valores de la parte superior del array, para no mover el resto de elementos del array. Esto es, por supuesto, más rápido.