전문가를 위한 질문 #define - 페이지 5

 
Alexandr Andreev :

테스트의 전체 코드를 알려주십시오.

보류, 하지만 다시 논의하기 위해 rand()를 사용하는 것은 의미가 없습니다. 옵션으로 inc ++ 변수로 대체하십시오.

 #define   SpeedTest(count_x10,msg,EX)        { ulong mss= GetMicrosecondCount (); ulong count=( ulong ) pow ( 10 ,count_x10); for ( ulong _i= 0 ;_i<count&&! _StopFlag ;_i++){EX;} \
                                               printf ( "%s: loops = %llu seconds=%.4f" ,msg,count,( double )( GetTickCount ()-mss) / 1000000.0 );}



//+------------------------------------------------------------------+
void OnStart ()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize (arr1, 100 );
   int cnt2 = ArrayResize (arr2, 200 );
   int cnt3 = ArrayResize (arr3, 300 );
   ulong sum = 0 ;

   SpeedTest( 3 , "ArraySize" ,
       for ( int i = 0 ; i < ArraySize (arr1); i++)
      {
         for ( int j = 0 ; j < ArraySize (arr2); j++)
         {
             for ( int k = 0 ; k < ArraySize (arr3); k++)
            {
               arr3[k] = rand ();
               sum += arr3[k];
            }
            arr2[j] = rand ();
            sum += arr2[j];
         }
         arr1[i] = rand ();
         sum += arr1[i];
      }
   )
   
   SpeedTest( 3 , "cnt" ,
       for ( int i = 0 ; i < cnt1; i++)
      {
         for ( int j = 0 ; j < cnt2; j++)
         {
             for ( int k = 0 ; k < cnt3; k++)
            {
               arr3[k] = rand ();
               sum += arr3[k];
            }
            arr2[j] = rand ();
            sum += arr2[j];
         }
         arr1[i] = rand ();
         sum += arr1[i];
      }
   )

}


예... 코드에 오류가 있습니다. 시간을 초 단위로 표시하고 싶지만 10배가 더 나옵니다. 정확히 1,000,000으로 나눴습니다. 누가 그 이유를 알려줄 수 있습니까?

 
Igor Makanu :

보류, 하지만 다시 논의하기 위해 rand()를 사용하는 것은 의미가 없습니다. 옵션으로 inc ++ 변수로 대체하십시오.


예... 코드에 오류가 있습니다. 시간을 초 단위로 표시하고 싶지만 10배가 더 나옵니다. 정확히 1,000,000으로 나눴습니다. 누가 그 이유를 알려줄 수 있습니까?

저스트 폭탄

여기에 그렇지 않은 것을 증명하는 코드가 있습니다.

 //+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
#define   SpeedTest(count_x10,msg,EX)        { ulong mss= GetMicrosecondCount (); ulong count=( ulong ) pow ( 10 ,count_x10); for ( ulong _i= 0 ;_i<count&&! _StopFlag ;_i++){EX;} \
                                               printf ( "%s: loops = %llu seconds=%.4f" ,msg,count,( double )( GetTickCount ()-mss)/ 1000000.0 );}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnStart ()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize (arr1, 100 );
   int cnt2 = ArrayResize (arr2, 200 );
   int cnt3 = ArrayResize (arr3, 300 );
   ulong sum = 0 ;

   
   SpeedTest( 3 , "cnt" ,
       for ( int i = 0 ; i < cnt1; i++)
      {
         for ( int j = 0 ; j < cnt2; j++)
         {
             for ( int k = 0 ; k < cnt3; k++)
            {
               arr3[k] = rand ();
               sum += arr3[k];
            }
            arr2[j] = rand ();
            sum += arr2[j];
         }
         arr1[i] = rand ();
         sum += arr1[i];
      }
   )

   SpeedTest( 3 , "ArraySize" ,
       for ( int i = 0 ; i < ArraySize (arr1); i++)
      {
         for ( int j = 0 ; j < ArraySize (arr2); j++)
         {
             for ( int k = 0 ; k < ArraySize (arr3); k++)
            {
               arr3[k] = rand ();
               sum += arr3[k];
            }
            arr2[j] = rand ();
            sum += arr2[j];
         }
         arr1[i] = rand ();
         sum += arr1[i];
      }
   )
}
 
Alexandr Andreev :

저스트 폭탄

여기에 그렇지 않은 것을 증명하는 코드가 있습니다.

방금 수표를 교환했습니다

 
Alexandr Andreev :

방금 수표를 교환했습니다

2020.11.02 21:01:38.590 22222 (USDCHF,H1) cnt: 루프 = 1000초=821.7159

2020.11.02 21:01:52.353 22222 (USDCHF,H1) ArraySize: 루프 = 1000초=807.9415


이를 기반으로 ArraySize가 변수를 사용하는 것보다 빠릅니다 =))) 테스트에 문제가 있습니다.
 
Roman :

네, 무슨 테스트요? ))
당신은 루프 조건의 두 가지 변형을 모두 보여주었습니다.
Igor는 또한 위의 코드를 가져왔습니다.
루프 조건에서 size 변수와 ArraySize()를 사용하여 루프 실행을 측정하기만 하면 됩니다.

그렇지 않으면 나를 증명해

그런 다음 내 테스트에서 어떤 이유로 든 동일합니다.

 
Alexandr Andreev :

방금 수표를 교환했습니다

네 해야 합니다

이번에는 게으르다

테스트를 외부 루프로 래핑하여 다음과 같이 얻었습니다.

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=13.4910

 
Igor Makanu :

네 해야 합니다

이번에는 게으르다

테스트를 외부 루프로 래핑하여 다음과 같이 얻었습니다.

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize: 루프 = 1000초=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt: 루프 = 1000초=13.4910

이제 루프에서 교체하십시오.

 
Alexandr Andreev :

이제 루프에서 교체하십시오.

놀라지 않겠습니다. 컴파일러가 코드를 즉석에서 최적화할 수 있다는 것을 알고 있습니다.

하지만 IMHO, 중첩 루프에서는 여전히 ArraySize()를 불필요하게 호출 하면 안 됩니다. 더 쉽고 저는 이미 역 루프를 사용하는 데 익숙합니다.

 for ( int i = ArraySize (arr)- 1 ; i >= 0 ; i--)

물론 때로는 불편할 때도 있지만 임시 변수를 통해 주기를 만듭니다. 옵션 번호 2

IMHO, 신뢰할 수 있으며 어떤 일이 일어날지 이해합니다.

 

글쎄, IMHO에 대해 나는 아무 말도 할 수 없습니다.

매우 큰 리플레이에서 승리는 첫 번째와 두 번째 방법에서 무작위가 되었습니다. 아마도 현재 순간의 프로세서 캐시와 총 부하에 따라 달라질 것입니다.

문제는 주기에 관한 것이 아니라 기능 해제에 관한 것이었습니다. 예를 들어 ArraySizehere가 있는 것처럼

결과;

for (int i=0; i<ArraySIize(mas); i++) == for (int i=0; i<size; i++)


그러나 두 번째 부분 에 크기 변수로 초기화를 추가하면. 그런 다음 첫 번째 방법이 이 변수를 초기화하고 이를 값과 동일시하는 시간 동안 선두를 차지합니다. 큰 반복에서만 눈에 띄게 됩니다.

 

루프 본문에서 배열의 크기를 변경하면 즉석 최적화가 더 이상 작동하지 않습니다.

따라서 코드를 변경하십시오.

 for ( int loop= 0 ; loop < 5 ;loop++)
   {
   int cnt1 = ArrayResize (arr1, 100 +loop);
   int cnt2 = ArrayResize (arr2, 200 +loop);
   int cnt3 = ArrayResize (arr3, 300 +loop);
   
   SpeedTest( 3 , "cnt" ,
.....

Alexandr Andreev :

그런 다음 첫 번째 방법이 이 변수를 초기화하고 값과 동일하게 만드는 시간을 주도합니다. 큰 반복에서만 눈에 띄게 됩니다.

초과하지 않는다

런타임 최적화가 주도할 것입니다.

프로파일러 없이는 이러한 간단한 기계 명령을 테스트할 수 없습니다. 일반적으로 루프에서 원하는 대로 작성할 수 있습니다. 옵션으로 테스터에서 테스트할 수 있습니다. 속도가 중요합니다.