예상치 못한 간단하고 유용한 발견을 프로그래머와 공유하고 싶습니다.
반올림 함수:
매우 느린 것으로 밝혀졌습니다. 내 MQL5 테스트에 따르면 반올림 프로세스의 속도를 4-5배 높이려면 다음 함수를 간단한 대안으로 바꿀 수 있습니다.
왜냐하면 이러한 함수는 종종 크고 중첩된 루프에서 사용되며 성능 향상은 상당히 중요할 수 있습니다.
아마도 함수를 호출 한다는 사실만으로도 매우 시간이 많이 소요될 것입니다(스택에 다른 데이터, 주소 등을 저장). 그리고 이 경우 함수 없이도 할 수 있습니다.
성능 테스트가 포함된 스크립트 파일을 첨부합니다.
이 라인으로 나만
y= round (x); -> y=( int )(x+ 0.5 );
동의하지 않는다. 수학 규칙에 따르면 소수 부분이 0.5보다 작으면 반올림됩니다. 그러나 0.5를 45.27에 더하면 더 큰 값으로 반올림됩니다.
이 라인으로 나만
동의하지 않는다. 수학 규칙에 따르면 소수 부분이 0.5보다 작으면 반올림됩니다. 그러나 0.5를 45.27에 더하면 더 큰 값으로 반올림됩니다.
#define MUL(x) ((x)+( 0.5 )) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart () { ulong t0,t1,t2,t3; int y0[],y1[],y2[]; ArrayResize (y0, 10000000 ); ArrayResize (y1, 10000000 ); ArrayResize (y2, 10000000 ); double x= 1.45 ; for ( int i= 0 ;i< 10000000 ;i++) { if (( int )(x+ 0.5 )!=( int ) round (x)) Print ( "ой..." ,x); x+= 0.27 ; y0[i]+= 0 ; y1[i]+= 0 ; y2[i]+= 0 ; } Print ( "y0[]: " ,y0[ 9999999 ], " / y1[]: " ,y1[ 9999999 ], " / y2[]: " ,y2[ 9999999 ]); x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y0[i]=( int ) MathRound (x); x+= 0.27 ; } t1= GetMicrosecondCount ()-t0; Print ( "y0[]: " ,y0[ 9999999 ]); x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y1[i]=( int )(x+ 0.5 ); x+= 0.27 ; } t2= GetMicrosecondCount ()-t0; Print ( "y1[]: " ,y1[ 9999999 ]); x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y2[i]=( int )MUL(x); x+= 0.27 ; } t3= GetMicrosecondCount ()-t0; Print ( "y2[]: " ,y2[ 9999999 ]); Print ( "Цикл округления 10 000 000 раз: (round) = " , IntegerToString (t1), " альтернатива с (int) = " , IntegerToString (t2), " альтернатива с (#define) = " , IntegerToString (t3), " микросекунд" ); } //+------------------------------------------------------------------+
이 라인으로 나만
동의하지 않는다. 수학 규칙에 따르면 소수 부분이 0.5보다 작으면 반올림됩니다. 그러나 0.5를 45.27에 더하면 더 큰 값으로 반올림됩니다.
무엇을 혼동하고 있습니까? 예를 들어 인증 코드를 구체적으로 삽입했습니다.
for ( int i= 0 ;i< 10000000 ;i++) { if (( int )(x+ 0.5 )!=( int ) round (x)) Print ( "ой..." ,x); x+= 0.27 ; }
내가 틀렸다면 Print 문 ( "oops..." ,x);
시도 - 모든 것이 정상입니다.
이 라인으로 나만
동의하지 않는다. 수학 규칙에 따르면 소수 부분이 0.5보다 작으면 반올림됩니다. 그러나 0.5를 45.27에 더하면 더 큰 값으로 반올림됩니다.
그리고 가져가서 확인하면? ))) int(45.27 + 0.5)는 어떻게 46을 줄까요? 동일한 45개가 유지됩니다.
나는 속도에 대해 말하는 것이 아니다.
당신은 무엇을 혼란스럽게 생각합니다. 예를 들어 인증 코드를 구체적으로 삽입했습니다.
내가 틀렸다면 Print 문이 실행될 것입니다 ( "oops..." ,x);
시도 - 모든 것이 정상입니다.
하지만 배열 에 데이터가 미리 채워져 있지 않으면 속도가 변경된다는 점은 여전히 흥미롭습니다.
#define _round(x) (int)((x)+( 0.5 )) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart () { ulong t0,t1,t2; int y0[],y1[]; ArrayResize (y0, 10000000 ); double x= 1.45 ; for ( int i= 0 ;i< 10000000 ;i++) { if (( int )(x+ 0.5 )!=( int ) round (x)) Print ( "ой..." ,x); x+= 0.27 ; y0[i]+= 0 ; // !!!!!!!!!!!!!! } x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y0[i]=( int )(x+ 0.5 ); x+= 0.27 ; } t1= GetMicrosecondCount ()-t0; x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y0[i]=_round(x); x+= 0.27 ; } t2= GetMicrosecondCount ()-t0; Print ( "Цикл округления 10 000 000 раз: с (int) = " , IntegerToString (t1), " с (#define) = " , IntegerToString (t2), " микросекунд" ); } //+------------------------------------------------------------------+
그리고 채우기
#define _round(x) ( int )((x)+( 0.5 )) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart () { ulong t0,t1,t2; int y0[],y1[]; ArrayResize (y0, 10000000 ); double x= 1.45 ; for ( int i= 1 ;i< 10000000 ;i++) { if (( int )(x+ 0.5 )!=( int ) round (x)) Print ( "ой..." ,x); x+= 0.27 ; y0[i]+= 1 ; // !!!!!!!!!!!!!! } x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y0[i]=( int )(x+ 0.5 ); x+= 0.27 ; } t1= GetMicrosecondCount ()-t0; x= 1.45 ; t0= GetMicrosecondCount (); for ( int i= 0 ;i< 10000000 ;i++) { y0[i]=_round(x); x+= 0.27 ; } t2= GetMicrosecondCount ()-t0; Print ( "Цикл округления 10 000 000 раз: с (int) = " , IntegerToString (t1), " с (#define) = " , IntegerToString (t2), " микросекунд" ); } //+------------------------------------------------------------------+
그리고 가져가서 확인하면? ))) int(45.27 + 0.5)는 어떻게 46을 줄까요? 동일한 45개가 유지됩니다.
동의합니다. 속도를 줄이세요. 말을 되돌려...
하지만 배열 에 데이터가 미리 채워져 있지 않으면 속도가 변경된다는 점은 여전히 흥미롭습니다.
그리고 채우기
y0[i]+= 0 ; // !!!!!!!!!!!!!!
내 생각에는 "#define"이 더 편리합니다.
#define _floor(x) ( int )((x)) #define _ceil(x) ( int )((x)+( 1 )) #define _round(x) ( int )((x)+( 0.5 ))
왜 오래 캐스팅하지 않습니까? 오버플로가 가능하지만 int 오버플로가 훨씬 쉽습니다.
예상치 못한 간단하고 유용한 발견을 프로그래머와 공유하고 싶습니다.
반올림 함수:
매우 느린 것으로 밝혀졌습니다. 내 MQL5 테스트에 따르면 반올림 프로세스의 속도를 4-5배 높이려면 다음 함수를 간단한 대안으로 바꿀 수 있습니다.
왜냐하면 이러한 함수는 종종 크고 중첩된 루프에서 사용되며 성능 향상은 상당히 중요할 수 있습니다.
아마도 함수를 호출 한다는 사실만으로도 매우 시간이 많이 소요될 것입니다(스택에 다른 데이터, 주소 등을 저장). 그리고 이 경우 함수 없이 할 수 있습니다.
성능 테스트가 포함된 스크립트 파일을 첨부합니다.