Verilen eleman(lar)ın bir dizisini temizleme - sayfa 15

 
Sergey Dzyublik :

[] operatörü hakkında benzer bir C++ dili için bir şekilde çok yavaş olduğu konuşulmuştu. ArrayCopy'nin onu bir ısıtma yastığı gibi yırtacak kadar doğrudan olduğunu düşünmemiştim.

operatörün içindeki artış hakkında ayrı bir soru.

 
Stanislav Dray :

Kendini düzeltip beni dışarı mı attın? iyi değil

Kimseyi kovmadı. indirildi, sonra geri döndü)))

 
Konstantin Nikitin :

Kimseyi kovmadı. indirildi, sonra geri döndü)))

11'i indirdin, benimki 12'si (aşağıda) ve 11'i düzeltip 13'ü olarak geri verdin.

 
TheXpert :

[] operatörü hakkında benzer bir C++ dili için bir şekilde çok yavaş olduğu konuşulmuştu. ArrayCopy'nin onu bir ısıtma yastığı gibi yırtacak kadar doğrudan olduğunu düşünmemiştim.

operatörün içindeki artış hakkında ayrı bir soru.

Evet, burada ekstra işlemler bile işe yaramaz. Bir döngü çalışması varsa. Mevcut öğeyi kopyalarken sınırların dışına çıkıp çıkmadığını karşılaştırmaya gerek yoktur. içinde olacaktır. Evet ve bir şeyi bir araya getirmek mantıklı ama bir değişken daha çekmenin de bir anlamı yok. Varsayılan ise, i var.
Kısacası, her küçük şey. Tamamen bilgi amaçlı yazılmıştır

 
Stanislav Dray :

11'i indirdin, benimki 12'si (aşağıda) ve 11'i düzeltip 13'ü olarak geri verdin.

Farketmedim. Dosyayı değiştirdi.

 

hala bu acımasız yarışmada çizilmiş :-)

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

Yine kontrol etmedim :-) teoride çalışması lazım..

 
Stanislav Dray :

Hata içeren testleri yorumladım (Semko ve Pavlov).

Teşekkürler, düzelttim.

Maksim Kuznetsov :

hala bu acımasız yarışmada çizilmiş :-)

Yine kontrol etmedim :-) teoride çalışması lazım..

etkin, ancak ilk seçenekte bir sorun var

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

Anlamadığım yürütme süresindeki farka geri dönüyorum, mantıkta neredeyse% 100 aynı, kontrol sayısı ve iki döngünün toplamı:

Tekrar ediyorum, neden Kuznetsov'un kodundan böyle bir seçenek:

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

bunun iki katından daha hızlı çalışır ve tam olarak aynı şeyi yapar:

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

Derleyicinin harikaları nelerdir?
Gerçekten böyle bir tasarım için:

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

derleyici, işlemci için bazı özel montajcı arama talimatları buluyor mu? Ama içeride ek bir i<j kontrolü var mı?

sonuçta, aynı şey aşağıdakiler için gözle görülür şekilde daha yavaş yapılır:

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

Ekli, gösteren komut dosyası kodudur.

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

Bu sık sık böyle olur. Görünüşe göre gereksiz bir çöplük yapıyorsun ve kendin için çok ilginç bir şey buluyorsun.

Geliştiriciler, yürütülebilir koda bakabilir misiniz, neden böyle bir fark var?

Sonuçta, gelecekte daha optimal algoritmalar oluşturmak için derleyicinin mantığını anlamanız gerekir.

Dosyalar:
TestLoop.mq5  10 kb
 
Nikolay Semko

İlginç bir gözlem. ve ilgi uğruna kodu koştu

 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 :

Anlamadığım yürütme süresindeki farka geri dönüyorum, mantıkta neredeyse% 100 aynı, kontrol sayısı ve iki döngünün toplamı:

Tekrar ediyorum, neden Kuznetsov'un kodundan böyle bir seçenek:

bunun iki katından daha hızlı çalışır ve tam olarak aynı şeyi yapar:

Derleyicinin harikaları nelerdir?
Gerçekten böyle bir tasarım için:

derleyici, işlemci için bazı özel montajcı arama talimatları buluyor mu? Ama içeride ek bir i<j kontrolü var mı?

sonuçta, aynı şey aşağıdakiler için gözle görülür şekilde daha yavaş yapılır:

Ekli, gösteren komut dosyası kodudur.

Bu sık sık böyle olur. Görünüşe göre gereksiz bir çöplük yapıyorsun ve kendin için çok ilginç bir şey buluyorsun.

Geliştiriciler, yürütülebilir koda bakabilir misiniz, neden böyle bir fark var?

Sonuçta, gelecekte daha optimal algoritmalar oluşturmak için derleyicinin mantığını anlamanız gerekir.

Bayrakların başarıyla eşleştiğini düşünüyorum:
http://osinavi.ru/asm/4.php

ve ekstra operatörler/karşılaştırmalar için...