Effacement d'un tableau d'élément(s) défini(s) - page 11

 
Nikolai Semko:

Bravo ! Après avoir corrigé quelques erreurs, vous m'avez fait tomber de mon piédestal même sans utiliser ArrayCopy. Échec et mat. :))

Ça vaut probablement la peine de changer
for(;;)

à

while(true)

Sortie toujours par la pause

P.S. Juste pour le fun, j'ai fait une copie directe sur tout le tableau.
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:
Ça vaut probablement la peine de changer

à

Sortie toujours par la pause

Cela ne fait aucune différence. Parmi les boucles infinies, je préfère for parce qu'il est plus court et vrai ne déroute pas les débutants.
 
Une grande douleur dans le cou pour les développeurs de l'optimiseur MT5/ME (builds 1945).
Terminal Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Mémoire : 5276 / 16250 Mb


Pourquoi le code :
arr[j++] = arr[i];

Fonctionne plus lentement que :
arr[j] = arr[i];
j++;



Si vous participez à ce concours sans aucune règle, vous devez copier le code du "leader" (actuellement Kuznetsov) et le modifier en fonction du comportement du système décrit ci-dessus.
Cela conduit à un gain stable d'environ 20 msec par rapport au temps d'exécution initial 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;
}
 

À propos, je suis curieux de savoir comment les résultats changeront si le tableau d'origine est une série. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
Si nous prenons ce concours sans règles, nous copions le code du "leader" (actuellement Kuznetsov) et le modifions en fonction du comportement du système décrit ci-dessus.

Nous obtenons un gain stable d'environ 20 ms par rapport au temps d'exécution initial de 740 ms :

Cela vaut la peine de l'ajouter. Si vous ne vous souciez pas de la séquence des éléments du tableau. Alors oui, c'est une excellente variante. S'il est important de maintenir la cohérence, alors il faut autre chose.

 

Pendant qu'on y est, voici ma version :

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

les résultats :

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 principe, la limite de vitesse a été atteinte. La prochaine étape est juste la micro-optimisation et le tripotage de la boucle for :

Je pense que le résultat de Nikolaï est une utilisation habile de ces micro-optimisations.

Dossiers :
 
Vladimir Pastushak:

Il y a un tableau contenant un ensemble de données de type 1,2,3,6,9,5,6,3,25,6,8,7,4 ; vous devez supprimer par exemple les valeurs 3 et obtenir le même tableau sans 3 et sans espaces vides dans la sortie...

Je cherche le moyen le plus rapide d'effacer les valeurs inutiles d'un tableau...

L'exemple suivant me vient à l'esprit

Peut-être existe-t-il un moyen plus rapide et moins cher ?

Vladimir, pourquoi est-ce nécessaire ?
Si je comprends bien, il faut le faire avec le tampon de l'indicateur. Mais ne serait-il pas plus logique de remplacer les valeurs vides et/ou "inutiles" par la valeur précédente ou, par exemple, par la moyenne arithmétique des valeurs extrêmes ? Il sera alors beaucoup plus rapide et la dimension du tableau restera la même.

 
Nikolai Semko:

Vladimir, pourquoi est-ce nécessaire ?
Si je comprends bien, il faut le faire avec le tampon de l'indicateur. Mais ne serait-il pas plus logique de remplacer les valeurs vides et/ou "inutiles" par la valeur précédente ou, par exemple, par la moyenne arithmétique des valeurs extrêmes ? Il sera alors beaucoup plus rapide et la dimension du tableau restera la même.

Cela est nécessaire pour afficher des informations, une grande quantité d'informations et effectuer d'autres calculs sur cette base. Une fonction de ce type est nécessaire pour vider le tableau des données non pertinentes. Et surtout, il doit fonctionner très rapidement ! Mon analogique est inférieur en termes de vitesse, il provoque des freezes lors de l'affichage des informations.

 
Nikolai Semko:

Vladimir, pourquoi est-ce nécessaire ?
Si j'ai bien compris, vous devez le faire avec un tampon indicateur. Mais ne serait-il pas plus logique de remplacer les valeurs vides et/ou "inutiles" par la valeur précédente ou la moyenne arithmétique des valeurs extrêmes, par exemple ? Il sera alors beaucoup plus rapide et la dimension du tableau restera la même.

Quand il y a plusieurs EAs avec un grand nombre de positions/ordres ouverts dans mql4, à mon avis, il est plus facile de garder le tableau avec les tickets et de vérifier si l'ordre est fermé en passant par le tableau au lieu d'essayer toutes les positions ouvertes avec la vérification du symbole et du magicien. Ainsi, si l'ordre est fermé, il doit être "rayé" du tableau. Dans de tels cas, j'avais l'habitude de copier le tableau "dans lui-même" et de réduire la taille du tableau d'une unité. Cela a été suggéré par Vasiliy Sokolov, merci beaucoup, je saurai que ce n'est pas l'option la plus difficile, car je n'ai jamais pensé à la vitesse. La raison pour laquelle la tâche consistait à supprimer plusieurs éléments égaux est une autre question...

ps Pendant que j'écrivais ceci, la réponse est déjà là. Donc la question est déjà fausse aussi... ))))))
 
Alexey Viktorov:

Quand il y a plusieurs EAs avec un grand nombre de positions/ordres ouverts dans mql4, à mon avis, il est plus facile de garder le tableau avec les tickets et de vérifier si l'ordre est fermé en passant par le tableau au lieu d'essayer toutes les positions ouvertes avec la vérification du symbole et du magicien. Ainsi, si l'ordre est fermé, il doit être "rayé" du tableau. Dans de tels cas, j'avais l'habitude de copier le tableau "dans lui-même" et de réduire la taille du tableau d'une unité. C'est Vasiliy Sokolov qui l'a suggéré, merci beaucoup, je vais savoir que ce n'est pas l'option la plus difficile, car je n'avais jamais pensé à la vitesse. La raison pour laquelle la tâche consistait à supprimer plusieurs éléments égaux est une autre question...

ps Pendant que j'écrivais, la réponse est déjà là. Il s'avère que la question est déjà fausse aussi... ))))))

J'ai à peu près tout compris à ce moment-là.

Si nous avons un tableau d'ordres, l'ordre n'est pas important, il est donc plus raisonnable d'utiliser la variante de Kuznetsov en remplissant les "trous" avec des valeurs de la partie supérieure du tableau, afin de ne pas déplacer le reste des éléments du tableau. C'est bien sûr plus rapide.

Raison: