Löschen eines Arrays mit definierten Element(en) - Seite 11

 
Nikolai Semko:

Bravo! Nachdem ich ein paar Fehler korrigiert habe, haben Sie mich vom Sockel gestoßen, auch ohne ArrayCopy zu verwenden. Schachmatt. :))

Es lohnt sich wahrscheinlich, die
for(;;)

zu

while(true)

Ausgang noch über Pause

P.S. Nur zum Spaß habe ich eine direkte Kopie über das gesamte Array laufen lassen.
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:
Es lohnt sich wahrscheinlich, die

zu

Ausgang noch über Pause

Es macht keinen Unterschied. Von den Endlosschleifen gefällt mir for besser, weil es kürzer ist und Neulinge nicht verwirrt.
 
Ein großes Ärgernis für die Entwickler des MT5/ME-Optimierers (Builds 1945).
Terminal Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Speicher: 5276 / 16250 Mb


Warum Code:
arr[j++] = arr[i];

Läuft langsamer als:
arr[j] = arr[i];
j++;



Wenn Sie ohne Regeln an diesem Wettbewerb teilnehmen, sollten Sie den Code des "Anführers" (derzeit Kuznetsov) kopieren und ihn entsprechend dem oben beschriebenen Systemverhalten ändern.
Dies führt zu einem stabilen Gewinn von etwa 20 ms gegenüber der ursprünglichen Laufzeit von 740 ms:

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

Ich bin übrigens neugierig, wie sich die Ergebnisse ändern, wenn die ursprüngliche Anordnung eine Reihe ist. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
Wenn wir diesen Wettbewerb ohne Regeln nehmen, kopieren wir den Code des "Führenden" (derzeit Kuznetsov) und ändern ihn entsprechend dem oben beschriebenen Verhalten des Systems.

Wir erhalten einen stabilen Gewinn von etwa 20 ms gegenüber der ursprünglichen Ausführungszeit von 740 ms:

Es lohnt sich, dies hinzuzufügen. Wenn Sie sich nicht um die Reihenfolge der Array-Elemente kümmern. Dann ja, es ist eine ausgezeichnete Variante. Wenn es wichtig ist, die Konsistenz aufrechtzuerhalten, dann ist etwas anderes erforderlich.

 

Und wenn wir schon dabei sind, hier ist meine 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;
}

Ergebnisse:

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. Im Prinzip ist die Höchstgeschwindigkeit erreicht. Der nächste Schritt ist nur eine Mikro-Optimierung und das Tüfteln an der for-Schleife:

Ich denke, Nikolais Ergebnis ist ein geschickter Einsatz solcher Mikro-Optimierungen.

Dateien:
 
Vladimir Pastushak:

Es gibt ein Array, das eine Reihe von Daten des Typs 1,2,3,6,9,5,6,3,25,6,8,7,4 enthält, die Sie benötigen, um z.B. Werte 3 zu entfernen und das gleiche Array ohne 3 und Leerzeichen in der Ausgabe zu erhalten...

Ich bin auf der Suche nach dem schnellsten Weg, um ein Array von unnötigen Werten zu löschen...

Das folgende Beispiel kommt mir in den Sinn

Vielleicht gibt es einen billigeren und schnelleren Weg?

Vladimir, warum ist das notwendig?
Wenn ich es richtig verstanden habe, muss dies mit dem Indikatorpuffer geschehen. Aber wäre es nicht logischer, leere und/oder "unnötige" Werte durch den vorherigen Wert oder z.B. das arithmetische Mittel der Extremwerte zu ersetzen? Dann geht es viel schneller und die Array-Dimension bleibt gleich.

 
Nikolai Semko:

Vladimir, warum ist das notwendig?
Wenn ich es richtig verstanden habe, muss dies mit dem Indikatorpuffer geschehen. Aber wäre es nicht logischer, leere und/oder "unnötige" Werte durch den vorherigen Wert oder z.B. das arithmetische Mittel der Extremwerte zu ersetzen? Dann geht es viel schneller und die Array-Dimension bleibt gleich.

Dies ist notwendig, um Informationen anzuzeigen, eine große Menge an Informationen zu erhalten und darauf aufbauend weitere Berechnungen durchzuführen. Eine Funktion dieser Art wird benötigt, um das Array von irrelevanten Daten zu befreien. Und das Wichtigste: Es muss sehr schnell gehen! Mein Analoggerät ist in Bezug auf die Geschwindigkeit unterlegen, es friert bei der Anzeige der Informationen ein.

 
Nikolai Semko:

Vladimir, warum ist das notwendig?
Wenn ich es richtig verstanden habe, müssen Sie das mit einem Indikatorpuffer tun. Aber wäre es nicht logischer, die leeren und/oder "unnötigen" Werte durch den vorherigen Wert oder das arithmetische Mittel der Extremwerte zu ersetzen? Dann geht es viel schneller und die Array-Dimension bleibt gleich.

Wenn es mehrere EAs mit einer großen Anzahl von offenen Positionen/Aufträgen in mql4 gibt, ist es meiner Meinung nach einfacher, das Array mit Tickets zu behalten und zu prüfen, ob der Auftrag geschlossen ist, indem man das Array durchgeht, anstatt alle offenen Positionen mit der Prüfung auf Symbol und Magier zu versuchen. Wenn der Auftrag also abgeschlossen ist, sollte er aus dem Array "durchgestrichen" werden. In solchen Fällen habe ich das Array "in sich selbst" kopiert und die Größe des Arrays um eins reduziert. Das wurde von Vasiliy Sokolov vorgeschlagen, vielen Dank, ich werde wissen, dass es nicht die schwierigste Option ist, da ich nie über die Geschwindigkeit nachgedacht habe. Warum die Aufgabe darin bestand, mehrere gleiche Elemente zu entfernen, ist eine andere Frage...

ps Während ich dies schrieb, war die Antwort schon da. Die Frage ist also auch schon falsch... ))))))
 
Alexey Viktorov:

Wenn es mehrere EAs mit einer großen Anzahl von offenen Positionen/Aufträgen in mql4 gibt, ist es meiner Meinung nach einfacher, das Array mit Tickets zu behalten und zu prüfen, ob der Auftrag geschlossen ist, indem man das Array durchgeht, anstatt alle offenen Positionen mit der Prüfung auf Symbol und Magier zu versuchen. Wenn der Auftrag also abgeschlossen ist, sollte er aus dem Array "durchgestrichen" werden. In solchen Fällen habe ich das Array "in sich selbst" kopiert und die Größe des Arrays um eins reduziert. Das wurde von Vasiliy Sokolov vorgeschlagen, vielen Dank, ich werde wissen, dass es nicht die schwierigste Option ist, da ich nie über die Geschwindigkeit nachgedacht habe. Warum die Aufgabe darin bestand, mehrere gleiche Elemente zu entfernen, ist eine andere Frage...

ps Während ich schrieb, war die Antwort schon da. Es stellt sich heraus, dass die Frage auch schon falsch ist... ))))))

Dann habe ich es ungefähr herausgefunden.

Bei einem Array von Aufträgen ist die Reihenfolge nicht wichtig, so dass es sinnvoller ist, die Kuznetsov-Variante zu verwenden, bei der "Löcher" mit Werten aus dem oberen Teil des Arrays gefüllt werden, um den Rest der Arrayelemente nicht zu verschieben. Das ist natürlich schneller.