Limpar um conjunto de elementos definidos - página 11

 
Nikolai Semko:

Bravo! Depois de corrigir alguns erros, você me derrubou do pedestal mesmo sem usar o ArrayCopy. Xeque-mate. :))

Provavelmente vale a pena mudar
for(;;)

para

while(true)

Ainda sair via pausa

P.S. Só por diversão, fez uma cópia direta em todo o conjunto.
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:
Provavelmente vale a pena mudar

para

Ainda sair via pausa

Isso não faz diferença. Dos loops infinitos, eu gosto mais porque é mais curto e verdadeiro não confunde os novatos.
 
Uma grande dor no pescoço para os desenvolvedores do otimizador de MT5/ME (construído em 1945).
Terminal Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Memória: 5276 / 16250 Mb


Por que codificar:
arr[j++] = arr[i];

Funciona mais lentamente do que:
arr[j] = arr[i];
j++;



Se você entrar neste concurso sem nenhuma regra, deverá copiar o código do "líder" (atualmente Kuznetsov) e modificá-lo de acordo com o comportamento do sistema descrito acima.
Isto leva a um ganho estável de cerca de 20 msec em relação ao tempo de execução inicial de 740 msec:

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;
}
 

A propósito, estou curioso como os resultados mudarão se a matriz original for uma série. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
Se aceitarmos este concurso sem regras, copiamos o código do "líder" (atualmente Kuznetsov) e o modificamos de acordo com o comportamento do sistema acima.

Temos um ganho estável de cerca de 20 ms em relação ao tempo de execução original de 740 ms:

Vale a pena acrescentar. Se você não se importa com a seqüência de elementos da matriz. Então sim, é uma excelente variante. Se é importante manter a consistência, então algo mais é necessário.

 

Já que estamos nisso, aqui está minha versão:

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. Em princípio, o limite de velocidade foi atingido. O próximo passo é apenas a micro-optimização e a manipulação do laço:

Acho que o resultado do Nikolai é um uso hábil de tais micro-optimizações.

Arquivos anexados:
 
Vladimir Pastushak:

Há uma matriz contendo um conjunto de dados do tipo 1,2,3,6,9,5,6,3,25,6,8,7,4 você precisa remover, por exemplo, os valores 3 e obter a mesma matriz sem 3 e espaços vazios na saída...

Procuro a maneira mais rápida de eliminar uma série de valores desnecessários.

O seguinte exemplo vem à mente

Talvez haja uma maneira mais barata e rápida ?

Vladimir, por que isso é necessário?
Pelo que entendi, isso tem que ser feito com o tampão indicador. Mas não seria mais lógico substituir os valores vazios e/ou "desnecessários" pelo valor anterior ou, por exemplo, a média aritmética dos valores extremos? Então será muito mais rápido e a dimensão da matriz permanecerá a mesma.

 
Nikolai Semko:

Vladimir, por que isso é necessário?
Pelo que entendi, isso tem que ser feito com o tampão indicador. Mas não seria mais lógico substituir os valores vazios e/ou "desnecessários" pelo valor anterior ou, por exemplo, a média aritmética dos valores extremos? Então será muito mais rápido e a dimensão da matriz permanecerá a mesma.

Isto é necessário para exibir informações, grande quantidade de informações e fazer cálculos adicionais com base nelas. Uma função deste tipo é necessária para limpar o conjunto de dados irrelevantes. E o mais importante, deve funcionar muito rapidamente! Meu analógico é inferior em termos de velocidade, causa o congelamento ao exibir as informações.

 
Nikolai Semko:

Vladimir, por que isso é necessário?
Pelo que entendi, você tem que fazer isso com o buffer indicador. Mas não seria mais lógico substituir os valores vazios e/ou "desnecessários" pelo valor anterior ou a média aritmética dos valores extremos, por exemplo? Então será muito mais rápido e a dimensão da matriz permanecerá a mesma.

Quando há vários EAs com um grande número de posições/ordens abertas em mql4, na minha opinião, é mais fácil manter a matriz com bilhetes e verificar se a ordem está fechada, passando pela matriz em vez de tentar todas as posições abertas com verificação de símbolo e mágico. Portanto, se a ordem for fechada, ela deve ser "riscada" da matriz. Nesses casos, eu costumava copiar a matriz "em si mesma" e reduzir o tamanho da matriz em um. Isso foi sugerido por Vasiliy Sokolov, muito obrigado, saberei que não é a opção mais difícil, pois nunca pensei em velocidade. Por que a tarefa era remover vários elementos iguais é outra questão...

ps Enquanto eu escrevia isto, a resposta já está lá. Portanto, a questão também já está errada... ))))))
 
Alexey Viktorov:

Quando há vários EAs com um grande número de posições/ordens abertas em mql4, na minha opinião, é mais fácil manter a matriz com bilhetes e verificar se a ordem está fechada, passando pela matriz em vez de tentar todas as posições abertas com verificação de símbolo e mágico. Portanto, se a ordem for fechada, ela deve ser "riscada" da matriz. Nesses casos, eu costumava copiar a matriz "em si mesma" e reduzir o tamanho da matriz em um. Isso foi sugerido por Vasiliy Sokolov, muito obrigado, saberei que não é a opção mais difícil, pois nunca pensei em velocidade. Por que a tarefa era remover vários elementos iguais é outra questão...

ps Enquanto eu estava escrevendo, a resposta já está lá. Acontece que a questão já está errada também... ))))))

Eu descobri então, grosso modo.

Se tivermos uma matriz de ordens, a ordem não é importante, então é mais razoável usar a variante do Kuznetsov com preenchimento de "furos" com valores da parte superior da matriz, de modo a não mover o resto dos elementos da matriz. Isto, claro, é mais rápido.

Razão: