Cancellare un array di elementi definiti - pagina 15

 
Sergey Dzyublik:

C'è già stata una discussione sull'operatore [], che è in qualche modo troppo lento per un linguaggio C++ come questo. Non pensavo che fosse così lento che ArrayCopy potesse strapparlo.

Questa è una domanda separata sugli incrementi all'interno degli operatori.

 
Stanislav Dray:

Perché ti sei sistemato e mi hai buttato fuori? Non va bene.

Non ho buttato fuori nessuno. Quello che , l'ho restituito )))

 
Konstantin Nikitin:

Non ha buttato fuori nessuno. Quello che lo hai restituito ))))

Bene, quindi hai scaricato l'11, il mio è il 12 (sotto) e tu hai corretto l'11 e l'hai restituito come il 13.

 
TheXpert:

C'è già stata una discussione sull'operatore [], che è in qualche modo troppo lento per un linguaggio C++ come questo. Non pensavo che fosse così lento che ArrayCopy potesse distruggerlo.

Questa è una domanda separata sugli incrementi all'interno degli operatori.

Qui non c'è nemmeno motivo di eseguire operazioni inutili. Se il looping è in corso. Non c'è bisogno di controllare se l'elemento corrente è fuori dai limiti quando viene copiato. Sarà all'interno dei confini. E non ha senso aggiungere qualcosa, o tirare una variabile in più. Se per default c'è una i.
Comunque, c'è tutta una serie di cose banali. Solo per informazione

 
Stanislav Dray:

Bene, quindi hai scaricato l'11, il mio è il 12 (sotto) e tu hai corretto l'11 e l'hai restituito come il 13.

Non ha prestato attenzione. Sostituito il file.

 

anche abbozzato in questo concorso spietato :-)

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

Di nuovo, non controllato :-) dovrebbe funzionare...

 
Stanislav Dray:

Hanno raccomandato test contenenti errori (Semko e Pavlov) .

Grazie, l'ho aggiustato.

Maxim Kuznetsov:

anche abbozzato in questo concorso spietato :-)

Non ho controllato di nuovo :-) dovrebbe funzionare...

incluso, ma c'è qualcosa di sbagliato con la prima variante

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 микросекунд
File:
 

Torno alla mia incompresa differenza nel tempo di esecuzione di quasi il 100% identico nella logica e nel numero di controlli e somme di due cicli:

Quindi, di nuovo, perché una tale variante dal codice di Kuznetsov:

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

funziona più del doppio più velocemente di questo, che fa esattamente la stessa cosa:

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

Quali sono le meraviglie del compilatore?
È davvero possibile un tale disegno:

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

il compilatore trova qualche comando speciale di ricerca dell'assemblatore per il processore? Ma c'è un ulteriore controllo i<j all'interno, vero?

Perché la stessa cosa attraverso per viene eseguita molto più lentamente:

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

Allego il codice dello script dimostrativo

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 микросекунд

Questo è il modo in cui spesso accade. Siete occupati con della spazzatura inutile e scoprite qualcosa di piuttosto interessante.

Sviluppatori, potreste dare un'occhiata al codice eseguibile e vedere cosa fa questa differenza?

È necessario comprendere la logica del compilatore per creare algoritmi più ottimali in futuro.

File:
TestLoop.mq5  10 kb
 
Nikolai Semko

Osservazione interessante. e per amor di interesse, ha eseguito il codice

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:

Torno alla mia incompresa differenza nel tempo di esecuzione di quasi il 100% identico nella logica e nel numero di controlli e somme di due cicli:

Quindi, di nuovo, perché una tale variante dal codice di Kuznetsov:

funziona più del doppio più velocemente di uno che fa esattamente la stessa cosa:

Quali sono le meraviglie del compilatore?
È davvero possibile per un costrutto come questo:

il compilatore trova qualche comando speciale di ricerca dell'assemblatore per il processore? Ma c'è un ulteriore controllo i<j all'interno, vero?

Perché la stessa cosa attraverso per viene eseguita molto più lentamente:

Allego il codice dello script dimostrativo

Questo è il modo in cui spesso accade. Siete occupati con della spazzatura inutile e scoprite qualcosa di piuttosto interessante.

Sviluppatori, potreste dare un'occhiata al codice eseguibile e vedere cosa fa questa differenza?

È necessario comprendere la logica del compilatore per creare algoritmi più ottimali in futuro.

Penso che sia un buon abbinamento per le bandiere:
http://osinavi.ru/asm/4.php

E per gli operatori/confronti inutili...