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

 
Sergey Dzyublik:

There was already a discussion about [] operator, that it is somehow too slow for C++ language like this. I didn't think it was so slow that ArrayCopy can tear it apart.

That's a separate question about increments inside operators.

 
Stanislav Dray:

Why did you fix yourself and throw me out? Not good.

I didn't throw anybody out. What , I returned )))

 
Konstantin Nikitin:

Didn't throw anyone out. What you returned ))))

well so you downloaded the 11th, mine is the 12th(below) and you fixed the 11th and returned it as the 13th.

 
TheXpert:

There was already a discussion about [] operator, that it is somehow too slow for C++ language like this. I didn't think it was so slow that ArrayCopy can tear it apart.

That's a separate question about increments inside operators.

There's not even any unnecessary operations here. If looping is in progress. There is no need to check if the current item is out of bounds when it is being copied. It will be inside the bounds. And there is no sense in adding something, or pulling one more variable. If by default, there is an i.
Anyway, there is all sorts of trivial stuff. Just for information

 
Stanislav Dray:

well so you downloaded the 11th, mine is the 12th(below) and you fixed the 11th and returned it as the 13th.

Didn't pay attention. Replaced the file.

 

also sketched in this ruthless competition :-)

template <typename T>
int copyFilter1(const T &src[],T &dst[],T x)
{
        int i=0,j=0,k;
        int total=ArraySize(src);
        ArrayResize(dst,total);
        for(;;) {
                // считаем сколько копировать
                for(k=0;k<total && src[i]!=x;)
                        k++;
                // копируем
                if (k) {        
                        ArrayCopy(dst,src,j,i,k);
                        i+=k;
                        j+=k;
                        total-=k;
                }
                // пропускаем
                for(k=0;k<total && src[i]==x;) 
                        k++;
                if (k) {
                        i+=k;
                        total-=k;
                } else break;
        }
        ArrayResize(dst,j);
        return j;
}

template <typename T>
int copyFilter2(const T &src[],T &dst[],T x)
{
        int i=0,j=0,k;
        int total=ArraySize(src);
        ArrayResize(dst,total);
        for(;i<total;) {
                // копируем всё что не равно x
                for(;i<total && src[i]!=x;i++,j++)
                        dst[j]=src[i];
                // пропускаем всё что равно x
                for(;i<total && src[i]==x;)
                        i++;
        }
        ArrayResize(dst,j);
        return j;
}

Again, not checked :-) should work...

 
Stanislav Dray:

Have recommended tests containing errors (Semko and Pavlov) .

Thanks, fixed it.

Maxim Kuznetsov:

also sketched in this merciless contest :-)

Again, not checked :-) should work...

included, but there is something wrong with the first variant

2018.11.15 06:19:01.929 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Pastushak   : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения - 141053 микросекунд
2018.11.15 06:19:01.934 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Korotky     : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   2494 микросекунд
2018.11.15 06:19:01.938 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Fedoseev    : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   1869 микросекунд
2018.11.15 06:19:01.941 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Semko       : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -    785 микросекунд
2018.11.15 06:19:01.945 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Nikitin     : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   2039 микросекунд
2018.11.15 06:19:01.952 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Vladimir    : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   4385 микросекунд
2018.11.15 06:19:01.961 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Peter       : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   7476 микросекунд
2018.11.15 06:19:01.965 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант fann95      : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   1255 микросекунд
2018.11.15 06:19:01.969 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov1  : Контрольная сумма = 7219.502578; элементов - 1000000; время выполнения -   2016 микросекунд
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov2  : Контрольная сумма = 7225.756203; элементов - 998992; время выполнения -   3965 микросекунд
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    
2018.11.15 06:19:01.975 ArrayDeleteValue__13 (.BrentCrud,M1)    === Порядок в массиве не сохраняется ===
2018.11.15 06:19:01.978 ArrayDeleteValue__13 (.BrentCrud,M1)    вариант Kuznetsov3  : Контрольная сумма = 7222.657252; элементов - 998992; время выполнения -    694 микросекунд
Files:
 

I come back to my misunderstood difference in execution time of almost 100% identical in logic and number of checks and sums of two loops:

So, again, why such a variant from Kuznetsov's code:

    for(;;)
     {
      while(arr[i]!=x && i<j) i++;
      while(arr[j]==x && i<j) j--;
      if(i<j)
        {
         arr[i++]=arr[j--];
        }
      else break;
     }

works more than twice as fast as the one that does exactly the same thing:

   while(i<j)
     {
      if(arr[i]==x)
         if(arr[j]!=x) arr[i++]=arr[j--];
      else j--;
      else i++;
     }

What are the wonders of the compiler?
Is it really possible for such a design:

while(arr[i]!=x && i<j) i++;

the compiler finds some special assembler's search command for the processor? But there is an additional check i<j inside, isn't there?

Because the same thing through for is executed much slower:

for (;;) if (arr[i]!=x && i<j) i++; else break;

I attach the code of the demonstration script

2018.11.15 13:30:51.354 TestLoop (EURUSD,D1)    вариант while:    Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 771 микросекунд
2018.11.15 13:30:51.357 TestLoop (EURUSD,D1)    вариант for:      Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 1051 микросекунд
2018.11.15 13:30:51.360 TestLoop (EURUSD,D1)    вариант slow:     Контрольная сумма = 7697.499145747599; элементов - 998975; время выполнения = 1531 микросекунд

This is how it often happens. You are busy with some unnecessary rubbish and find out something rather interesting.

Developers, could you have a look at the executable code and see what makes this difference?

You need to understand the logic of the compiler in order to create more optimal algorithms in the future.

Files:
TestLoop.mq5  10 kb
 
Nikolai Semko

Interesting observation. and for the sake of interest, ran the code

void OnStart()
{
     int array[], arr[];
     ArrayResize(arr,1000000);
     for(int i=0; i<1000000;i++)
          arr[i] = rand()%1000;

     int i=0;
     ulong t=GetMicrosecondCount();
     for(; i<1000000; i++)
          int j = arr[i];
     t = GetMicrosecondCount()-t;
     Print("FOR: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     for(;;)
     {
          if( i>=1000000 )
               break;
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("FOR-1: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     while(i<1000000)
     {
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("WHILE: ", t);
     
     t=GetMicrosecondCount();
     i=0;
     while(true)
     {
          if( i>=1000000 )
               break;
          int j = arr[i];
          i++;
     }
     t = GetMicrosecondCount()-t;
     Print("WHILE-1: ", t);
}


 
Nikolai Semko:

I come back to my misunderstood difference in execution time of almost 100% identical in logic and number of checks and sums of two loops:

So, again, why such a variant from Kuznetsov's code:

works more than twice as fast as one that does exactly the same thing:

What are the wonders of the compiler?
Is it really possible for a construct like this:

the compiler finds some special assembler's search command for the processor? But there is an additional check i<j inside, isn't there?

Because the same thing through for is executed much slower:

I attach the code of the demonstrating script

This is how it often happens. You are busy with some unnecessary rubbish and find out something rather interesting.

Developers, could you have a look at the executable code and see what makes this difference?

You need to understand the logic of the compiler in order to create more optimal algorithms in future.

I think it's a good match for the flags:
http://osinavi.ru/asm/4.php

And for for unnecessary operators/comparisons...