Clearing an array of defined element(s) - page 11

 
Nikolai Semko:

Bravo! After correcting a couple of errors, you've knocked me off the pedestal even without using ArrayCopy. Checkmate. :))

It's probably worth changing
for(;;)

to

while(true)

Still exit via break

P.S. Just for fun, ran a direct copy across the whole 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:
It's probably worth changing

to

Still exit via break

It makes no difference. Of the infinite loops, I like for better because it's shorter and true doesn't confuse newbies.
 
A great pain in the neck for developers of MT5/ME optimizer (builds 1945).
Terminal Windows 10 (build 17134) x64, IE 11, UAC, Intel Core i7-7700HQ @ 2.80GHz, Memory: 5276 / 16250 Mb


Why code:
arr[j++] = arr[i];

Runs slower than:
arr[j] = arr[i];
j++;



If you enter this contest without any rules, you should copy the code of the "leader" (currently Kuznetsov) and modify it in accordance with the above-described system behavior.
This leads to a stable gain of about 20 msec from the initial 740 msec runtime:

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

By the way, I'm curious how the results will change if the original array is a series. ArraySetAsSeries(arr,true)

 
Sergey Dzyublik:
If we take this contest without rules, we copy the code of the "leader" (currently Kuznetsov) and modify it according to the above behavior of the system.

We get a stable gain of about 20 ms from the original 740 ms execution time:

It's worth adding. If you don't care about the sequence of array elements. Then yes, it is an excellent variant. If it's important to maintain consistency, then something else is needed.

 

While we're at it, here's my 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;
}

results:

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 principle, the speed limit has been reached. Next step is just micro-optimization and fiddling with the for loop:

I think Nikolai's result is a skillful use of such micro-optimizations.

Files:
 
Vladimir Pastushak:

There is an array containing a set of data of type 1,2,3,6,9,5,6,3,25,6,8,7,4 you need to remove e.g. values 3 and get the same array without 3 and empty spaces in the output...

I'm looking for the fastest way to clear an array of unnecessary values...

The following example comes to mind

Maybe there is a cheaper and faster way ?

Vladimir, why is this necessary?
As I understand it, it has to be done with the indicator buffer. But wouldn't it be more logical to replace empty and/or "unnecessary" values with the previous value or, for example, the arithmetic mean of the extreme values? Then it will be much faster and the array dimension will remain the same.

 
Nikolai Semko:

Vladimir, why is this necessary?
As I understand it, it has to be done with the indicator buffer. But wouldn't it be more logical to replace empty and/or "unnecessary" values with the previous value or, for example, the arithmetic mean of the extreme values? Then it will be much faster and the array dimension will remain the same.

This is necessary for displaying information, large amount of information and making further calculations based on it. A function of this kind is needed to clear the array of irrelevant data. And most importantly, it must work very quickly! My analogue is inferior in terms of speed, it causes freezes when displaying the information.

 
Nikolai Semko:

Vladimir, why is this necessary?
As I understand it, you have to do it with indicator buffer. But wouldn't it be more logical to replace the empty and/or "unnecessary" values with the previous value or the arithmetic mean of the extreme values, for example? Then it will be much faster and the array dimension will remain the same.

When there are multiple EAs with a large number of open positions/orders in mql4, in my opinion, it is easier to keep the array with tickets and check if the order is closed by going through the array instead of trying all open positions with check for symbol and magician. So, if the order is closed, it should be "crossed out" of the array. In such cases, I used to copy the array "into itself" and reduce the array size by one. That was suggested by Vasiliy Sokolov, thanks a lot, I will know it's not the hardest option, as I never thought about speed. Why the task was to remove several equal elements is another question...

ps While I was writing this, the answer is already there. So the question is already wrong too... ))))))
 
Alexey Viktorov:

When there are multiple EAs with a large number of open positions/orders in mql4, in my opinion, it is easier to keep the array with tickets and check if the order is closed by going through the array instead of trying all open positions with check for symbol and magician. So, if the order is closed, it should be "crossed out" of the array. In such cases, I used to copy the array "into itself" and reduce the array size by one. That was suggested by Vasiliy Sokolov, thank you very much, I will know it's not the hardest option, as I never thought about speed. Why the task was to remove several equal elements is another question...

ps While I was writing, the answer is already there. It turns out that the question is already wrong too... ))))))

I roughly figured it out then.

If we have an array of orders, the order is not important, so it is more reasonable to use the Kuznetsov's variant with filling "holes" with values from the upper part of the array, so as not to move the rest of the array elements. This is of course faster.

Reason: