Cancellare un array di elementi definiti - pagina 11

 
Nikolai Semko:

Bravo! Dopo aver corretto un paio di errori, mi hai fatto scendere dal piedistallo anche senza usare ArrayCopy. Scacco matto. :))

Probabilmente vale la pena di cambiare
for(;;)

a

while(true)

Ancora uscita via break

P.S. Solo per divertimento, ho eseguito una copia diretta su tutto l'array.
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:
Probabilmente vale la pena di cambiare

a

Ancora uscita via break

Non fa differenza. Dei cicli infiniti, mi piace di più perché è più breve e vero non confonde i neofiti.
 
Un grande dolore al collo per gli sviluppatori dell'ottimizzatore MT5/ME (builds 1945).
Terminale Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Memoria: 5276 / 16250 Mb


Perché il codice:
arr[j++] = arr[i];

Funziona più lentamente di:
arr[j] = arr[i];
j++;



Se si partecipa a questo concorso senza regole, si dovrebbe copiare il codice del "leader" (attualmente Kuznetsov) e modificarlo in conformità con il comportamento del sistema sopra descritto.
Questo porta ad un guadagno stabile di circa 20 msec dal tempo di esecuzione iniziale di 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 proposito, sono curioso di sapere come cambiano i risultati se l'array originale è una serie. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
Se prendiamo questa gara senza regole, copiamo il codice del "leader" (attualmente Kuznetsov) e lo modifichiamo secondo il comportamento del sistema di cui sopra.

Otteniamo un guadagno stabile di circa 20 ms dal tempo di esecuzione originale di 740 ms:

Vale la pena di aggiungere. Se non vi interessa la sequenza degli elementi dell'array. Allora sì, è una variante eccellente. Se è importante mantenere la coerenza, allora è necessario qualcos'altro.

 

Già che ci siamo, ecco la mia versione:

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

risultati:

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. In linea di principio, il limite di velocità è stato raggiunto. Il prossimo passo è solo la micro-ottimizzazione e l'armeggiare con il ciclo for:

Penso che il risultato di Nikolai sia un uso abile di queste micro-ottimizzazioni.

File:
 
Vladimir Pastushak:

C'è un array che contiene un insieme di dati di tipo 1,2,3,6,9,5,6,3,25,6,8,7,4 è necessario rimuovere ad esempio i valori 3 e ottenere lo stesso array senza 3 e spazi vuoti nell'output...

Sto cercando il modo più veloce per cancellare un array di valori non necessari...

Mi viene in mente il seguente esempio

Forse c'è un modo più economico e veloce?

Vladimir, perché è necessario?
Da quanto ho capito, deve essere fatto con il buffer dell'indicatore. Ma non sarebbe più logico sostituire i valori vuoti e/o "inutili" con il valore precedente o, per esempio, la media aritmetica dei valori estremi? Allora sarà molto più veloce e la dimensione dell'array rimarrà la stessa.

 
Nikolai Semko:

Vladimir, perché è necessario?
Da quanto ho capito, deve essere fatto con il buffer dell'indicatore. Ma non sarebbe più logico sostituire i valori vuoti e/o "inutili" con il valore precedente o, per esempio, la media aritmetica dei valori estremi? Allora sarà molto più veloce e la dimensione dell'array rimarrà la stessa.

Questo è necessario per visualizzare le informazioni, una grande quantità di informazioni e fare ulteriori calcoli basati su di esse. Una funzione di questo tipo è necessaria per cancellare l'array di dati irrilevanti. E soprattutto, deve funzionare molto rapidamente! Il mio analogico è inferiore in termini di velocità, causa dei blocchi durante la visualizzazione delle informazioni.

 
Nikolai Semko:

Vladimir, perché è necessario?
Da quanto ho capito, bisogna farlo con il buffer dell'indicatore. Ma non sarebbe più logico sostituire i valori vuoti e/o "inutili" con il valore precedente o la media aritmetica dei valori estremi, per esempio? Allora sarà molto più veloce e la dimensione dell'array rimarrà la stessa.

Quando ci sono più EA con un gran numero di posizioni/ordini aperti in mql4, secondo me, è più facile mantenere l'array con i ticket e controllare se l'ordine è chiuso passando attraverso l'array invece di provare tutte le posizioni aperte con controllo per simbolo e mago. Quindi, se l'ordine è chiuso, dovrebbe essere "cancellato" dall'array. In questi casi, ero solito copiare l'array "in se stesso" e ridurre la dimensione dell'array di uno. Questo è stato suggerito da Vasiliy Sokolov, grazie mille, saprò che non è l'opzione più difficile, perché non ho mai pensato alla velocità. Perché il compito era quello di rimuovere diversi elementi uguali è un'altra domanda...

ps Mentre scrivevo questo, la risposta è già lì. Quindi anche la domanda è già sbagliata... ))))))
 
Alexey Viktorov:

Quando ci sono più EA con un gran numero di posizioni/ordini aperti in mql4, secondo me, è più facile mantenere l'array con i ticket e controllare se l'ordine è chiuso passando attraverso l'array invece di provare tutte le posizioni aperte con controllo per simbolo e mago. Quindi, se l'ordine è chiuso, dovrebbe essere "cancellato" dall'array. In questi casi, ero solito copiare l'array "in se stesso" e ridurre la dimensione dell'array di uno. Questo è stato suggerito da Vasiliy Sokolov, grazie mille, saprò che non è l'opzione più difficile, perché non ho mai pensato alla velocità. Perché il compito era quello di rimuovere diversi elementi uguali è un'altra domanda...

ps Mentre scrivevo, la risposta è già lì. Si scopre che anche la domanda è già sbagliata... ))))))

Allora l'ho capito più o meno.

Se abbiamo un array di ordini, l'ordine non è importante, quindi è più ragionevole usare la variante di Kuznetsov con il riempimento dei "buchi" con valori dalla parte superiore dell'array, in modo da non spostare il resto degli elementi dell'array. Questo è ovviamente più veloce.