주어진 요소의 배열 지우기 - 페이지 15

 
Sergey Dzyublik :

유사한 C ++ 언어에 대해 어떻게 든 너무 느리다는 [] 연산자에 대한 이야기가 이미 있었습니다. ArrayCopy 가 가열 패드처럼 찢어 버릴 정도로 직접적이라고 생각하지 않았습니다.

연산자 내부의 증분에 대해서는 별도의 질문입니다.

 
Stanislav Dray :

글쎄, 당신은 당신 자신을 수정하고 나를 던졌습니다? 안좋다

아무도 쫓아내지 않았습니다. 한 항목을 다운로드한 다음 반환)))

 
Konstantin Nikitin :

아무도 쫓아내지 않았습니다. 한 항목을 다운로드한 다음 반환)))

글쎄요, 당신은 11일을 다운로드했고 내 것은 12일(아래)이고 11일을 수정하고 13일로 반환했습니다.

 
TheXpert :

유사한 C ++ 언어에 대해 어떻게 든 너무 느리다는 [] 연산자에 대한 이야기가 이미 있었습니다. ArrayCopy가 가열 패드처럼 찢어 버릴 정도로 직접적이라고 생각하지 않았습니다.

연산자 내부의 증분에 대해서는 별도의 질문입니다.

예, 추가 작업조차도 여기에서 쓸모가 없습니다. 사이클 실행이 있는 경우. 현재 요소를 복사할 때 범위를 벗어났는지 여부를 비교할 필요가 없습니다. 안에 있을 것입니다. 예, 무엇인가를 함께 모으는 것은 이치에 맞지만, 변수를 하나 더 가져오는 것도 의미가 없습니다. 기본값인 경우 i 가 있습니다.
요컨대, 모든 작은 것. 순전히 작성된 정보를 위해

 
Stanislav Dray :

글쎄요, 당신은 11일을 다운로드했고 내 것은 12일(아래)이고 11일을 수정하고 13일로 반환했습니다.

눈치채지 못했다. 파일을 교체했습니다.

 

이 무자비한 대회에서 여전히 스케치 :-)

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

다시, 나는 확인하지 않았다 :-) 그것은 이론상으로 작동해야 한다 ..

 
Stanislav Dray :

오류가 포함된 테스트를 주석 처리했습니다(Semko 및 Pavlov).

감사합니다. 수정했습니다.

막심 쿠즈네초프 :

이 무자비한 대회에서 여전히 스케치 :-)

다시, 나는 확인하지 않았다 :-) 그것은 이론상으로 작동해야 한다 ..

활성화되었지만 첫 번째 옵션에 문제가 있습니다.

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

내가 이해하지 못한 실행 시간의 차이로 돌아갑니다 . 논리와 검사 횟수 및 두 사이클의 합이 거의 100% 동일합니다.

그래서 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 ;
     }

정확히 동일한 작업을 수행하는 이것보다 두 배 이상 빠르게 작동합니다.

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

컴파일러의 놀라운 점은 무엇입니까?
정말 그런 디자인을 위해:

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

컴파일러가 프로세서에 대한 특별한 어셈블러 검색 명령을 찾았습니까? 그러나 내부에 추가 검사 i<j가 있습니까?

결국 동일한 작업이 다음을 통해 눈에 띄게 느리게 수행됩니다.

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

첨부된 것은 시연 스크립트 코드입니다.

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

그런 일이 자주 발생합니다. 당신은 불필요한 쓰레기를 만들고 자신에게 매우 흥미로운 것을 찾는 것 같습니다.

개발자 여러분, 실행 가능한 코드를 볼 수 있습니까? 왜 그런 차이가 있습니까?

결국, 미래에 더 최적의 알고리즘을 만들기 위해서는 컴파일러의 논리를 이해해야 합니다.

파일:
TestLoop.mq5  10 kb
 
니콜라이 셈코

흥미로운 관찰입니다. 관심을 위해 코드를 실행했습니다.

 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 :

내가 이해하지 못한 실행 시간의 차이로 돌아갑니다 . 논리와 검사 횟수 및 두 사이클의 합이 거의 100% 동일합니다.

그래서 나는 Kuznetsov의 코드에서 그러한 옵션을 반복합니다.

정확히 동일한 작업을 수행하는 이것보다 두 배 이상 빠르게 작동합니다.

컴파일러의 놀라운 점은 무엇입니까?
정말 그런 디자인을 위해:

컴파일러가 프로세서에 대한 특별한 어셈블러 검색 명령을 찾았습니까? 그러나 내부에 추가 검사 i<j가 있습니까?

결국 동일한 작업이 다음을 통해 눈에 띄게 느려집니다.

첨부된 것은 시연 스크립트 코드입니다.

그런 일이 자주 발생합니다. 당신은 불필요한 쓰레기를 만들고 자신에게 매우 흥미로운 것을 찾는 것 같습니다.

개발자 여러분, 실행 가능한 코드를 볼 수 있습니까? 왜 그런 차이가 있습니까?

결국, 미래에 더 최적의 알고리즘을 만들기 위해서는 컴파일러의 논리를 이해해야 합니다.

플래그가 성공적으로 일치했다고 생각합니다.
http://osinavi.ru/asm/4.php

추가 연산자/비교를 위해...