예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 스누즈마다 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 그래서 - 이것은 아무것도 아닌 컴퓨팅 리소스 의 끔찍한 낭비입니다. 왜냐하면 가격과 보류 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 스누즈마다 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 따라서 이것은 쓸데없는 컴퓨팅 리소스 의 끔찍한 낭비입니다. 왜냐하면 가격과 보류 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
NormalizeDouble()은 매우 비싼 함수입니다. 따라서 잊어 버리는 것이 좋습니다.
다음은 NormalizeDouble()과 int를 사용한 정규화의 차이점을 보여주는 스크립트입니다.
#define SIZE 1000000int Ceil ( double x) { return (x-( int )x> 0 )?( int )x+ 1 :( int )x;}
int Round( double x) { return (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 );}
int Floor( double x) { return (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x;}
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart ()
{
double a[SIZE];
double s1= 0 ,s2= 0 , s3= 0 ;
for ( int i= 0 ;i<SIZE;i++) a[i]=( rand ()- 16384 )/ M_PI ;
ulong t1= GetMicrosecondCount ();
for ( int i= 0 ;i<SIZE;i++) s1+=a[i];
t1= GetMicrosecondCount ()-t1;
ulong t2= GetMicrosecondCount ();
for ( int i= 0 ;i<SIZE;i++) s2+= NormalizeDouble (a[i], 5 );
t2= GetMicrosecondCount ()-t2;
ulong t3= GetMicrosecondCount ();
for ( int i= 0 ;i<SIZE;i++) s3+=Round(a[i]* 100000 );
s3/= 100000 ;
t3= GetMicrosecondCount ()-t3;
Print ( "простая сумма - " + string (t1)+ " микросекунд, сумма = " + DoubleToString (s1, 18 ));
Print ( "сумма с NormalizeDouble - " + string (t2)+ " микросекунд, сумма = " + DoubleToString (s2, 18 ));
Print ( "сумма, нормализированная через int - " + string (t3)+ " микросекунд, сумма = " + DoubleToString (s3, 18 ));
}
Nikolai Semko : 위협 및 int를 통한 정규화는 훨씬 더 정확합니다(이는 정규화의 마지막 숫자(파란색으로 강조 표시됨) 뒤에 있는 9의 숫자로 알 수 있음).
테스트가 잘못되었습니다. 마지막에 한 번만 100000.0으로 나누는 이유는 무엇입니까? 각 반복에서 실행한 다음 요약해야 합니다. 그러면 공정한 비교가 될 것입니다. 그래서 정규화가 없고 테스트 알고리즘을 최적화했습니다. 당연히 더 빠르고 정확할 것입니다(누적 오차가 줄어들기 때문에)
예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 각 스누즈에 대해 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 그래서 - 이것은 쓸데없는 컴퓨팅 자원 의 끔찍한 낭비입니다. 왜냐하면 가격 및 보류 중인 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
나는 속도를 위해 미친 버전을 확인하기로 결정했다. 그리고 결과는 놀랐습니다. 사전 정규화 된 double의 비교는 double이 epsilon을 통해 또는 int로 변환을 통해 비교되는 경우보다 평균적으로 훨씬 느립니다.
#define SIZE 1000000int Ceil ( double x) { return (x-( int )x> 0 )?( int )x+ 1 :( int )x;}
int Round( double x) { return (x> 0 )?( int )(x+ 0.5 ):( int )(x- 0.5 );}
int Floor( double x) { return (x> 0 )?( int )x:(( int )x-x> 0 )?( int )x- 1 :( int )x;}
bool is_equal( double d1, double d2, double e= 0.000000001 ) { returnfabs (d1-d2)<e;}
voidOnStart ()
{
double a[SIZE], a_norm[SIZE];
int s1= 0 ,s2= 0 , s3= 0 ;
for ( int i= 0 ;i<SIZE;i++) {
a[i]=( rand ()- 16384 )/ 1641.1452 ;
a_norm[i]= NormalizeDouble (a[i], 2 );
}
double test = 1.11 ;
ulong t1= GetMicrosecondCount ();
for ( int i= 0 ;i<SIZE;i++) if (a_norm[i]==test) s1++;
t1= GetMicrosecondCount ()-t1;
ulong t2= GetMicrosecondCount ();
for ( int i= 0 ;i<SIZE;i++) if (is_equal(a[i],test, 0.005 )) s2++;
t2= GetMicrosecondCount ()-t2;
ulong t3= GetMicrosecondCount ();
int test_int = test* 100 ;
for ( int i= 0 ;i<SIZE;i++) if (Round(a[i]* 100 )==test_int) s3++;
t3= GetMicrosecondCount ()-t3;
Print ("простое сравнение предварительно нормализированых double - " + string (t1)+ " микросекунд, всего совпадений = "+ string (s1));
Print ("сравнение double через эпсилон - " + string (t2)+ " микросекунд, всего совпадений = "+ string (s2));
Print ("сравнение double через преобразование в int - " + string (t3)+ " микросекунд, всего совпадений = "+ string (s3));
}
결과:
2020.08 . 1014 : 31 : 39.620 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 900 микросекунд, всего совпадений = 4862020.08 . 1014 : 31 : 39.620 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 723 микросекунд, всего совпадений = 4862020.08 . 1014 : 31 : 39.620 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 805 микросекунд, всего совпадений = 4862020.08 . 1014 : 31 : 42.607 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 1533 микросекунд, всего совпадений = 4882020.08 . 1014 : 31 : 42.607 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 758 микросекунд, всего совпадений = 4882020.08 . 1014 : 31 : 42.607 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 790 микросекунд, всего совпадений = 4882020.08 . 1014 : 31 : 44.638 TestCompareDouble (USDCAD,H4) простое сравнение предварительно нормализированых double - 986 микросекунд, всего совпадений = 4722020.08 . 1014 : 31 : 44.638 TestCompareDouble (USDCAD,H4) сравнение double через эпсилон - 722 микросекунд, всего совпадений = 4722020.08 . 1014 : 31 : 44.638 TestCompareDouble (USDCAD,H4) сравнение double через преобразование в int - 834 микросекунд, всего совпадений = 472
나는 많은 것이 프로세서의 참신함과 아키텍처에 달려 있고 누군가에게는 결과가 다를 수 있다는 점을 배제하지 않습니다.
솔직히 위협 - 왜 이런 일이 발생하는지 이해조차 되지 않습니다. 컴파일러는 난수의 합으로 최적화할 것이 없는 것 같습니다. 대괄호에서 반올림을 수행할 수 없습니다. 프로세서에서 double을 비교하는 것은 하나의 명령인 것 같습니다. 엡실론 비교 옵션(가장 빠른 옵션)을 사용하면 두 배를 비교하는 연산이 계속 발생하지만, 이 경우에는 3개의 매개변수를 전달하고 1개의 빼기 연산으로 함수를 추가로 호출합니다. 두 개의 이중 비교 연산의 성능은 실제로 변수 자체의 값에 달려 있습니까? 나는 의심한다. 젠장, 이해가 안 돼요. 도와주세요 - 내가 무엇을 고려하지 않았거나 어디에서 실수를 했습니까?
반올림만 일반 round(), ceil(), floor()를 통하지 않습니다. 그들은 또한 두 배를 반환합니다.
그리고 이를 통해 일반 작업보다 더 빠르게 작업합니다.
더 빠를 수도 있지만 잘못된 것뿐입니다.
직접 해보셨나요?
노력하다:
산출:
12346이어야 합니다. is ceil (" 위에서 가장 가까운 정수 값을 반환합니다 .")첫 번째 경우에는 12345가 얻어집니다. 이중 유형 17의 유효 숫자는 18입니다.
사실, 당신은 두 배를 비교할 수 없습니다. 그냥 어려운 규칙입니다.
물론, 두 배를 서로 직접 비교할 수 있고 때로는 필요할 수도 있습니다.
예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 스누즈마다 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 그래서 - 이것은 아무것도 아닌 컴퓨팅 리소스 의 끔찍한 낭비입니다. 왜냐하면 가격과 보류 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
fxsaber :
물론, 두 배를 서로 직접 비교할 수 있고 때로는 필요할 수도 있습니다.
예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 스누즈마다 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 따라서 이것은 쓸데없는 컴퓨팅 리소스 의 끔찍한 낭비입니다. 왜냐하면 가격과 보류 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
NormalizeDouble()은 매우 비싼 함수입니다. 따라서 잊어 버리는 것이 좋습니다.
다음은 NormalizeDouble()과 int를 사용한 정규화의 차이점을 보여주는 스크립트입니다.
결과:
위협 및 int를 통한 정규화는 훨씬 더 정확합니다(이는 정규화의 마지막 숫자(파란색으로 강조 표시됨) 뒤에 있는 9의 숫자로 알 수 있음).NormalizeDouble()은 매우 비싼 함수입니다. 따라서 잊어 버리는 것이 좋습니다.
다음은 NormalizeDouble()과 int를 사용한 정규화의 차이점을 보여주는 스크립트입니다.
결과:
위협 및 int를 통한 정규화는 훨씬 더 정확합니다(이는 정규화의 마지막 숫자(파란색으로 강조 표시됨) 뒤에 있는 9의 숫자로 알 수 있음).double이 아닌 long을 통해 요약하면 결과가 훨씬 더 인상적입니다. 왜냐하면 int를 통한 합계(총 합계의 후속 나누기를 통한 곱셈 및 반올림)는 일반적인 이중 합계보다 빠르게 계산됩니다.
결과:
double이 아닌 long을 통해 요약하면 결과가 훨씬 더 인상적입니다. 왜냐하면 int를 통한 합계(총 합계의 후속 나누기를 통한 곱셈 및 반올림)는 일반적인 이중 합계보다 빠르게 계산됩니다.
결과:
비교를 위해 Decimal 을 추가합니다.
잘못된 링크, 완전한 구현이 없습니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 그래서 - 이것은 아무것도 아닌 컴퓨팅 리소스 의 끔찍한 낭비입니다.
이것을 어떻게 압니까? 결국 가격이 정규화되지 않은 경우에도 검사는 정규화 없이 간단하게 수행됩니다.
가격이 ticksize의 배수임을 감안할 때
위협 및 int를 통한 정규화는 훨씬 더 정확합니다(이는 정규화의 마지막 숫자(파란색으로 강조 표시됨) 뒤에 있는 9의 숫자로 알 수 있음).
테스트가 잘못되었습니다. 마지막에 한 번만 100000.0으로 나누는 이유는 무엇입니까? 각 반복에서 실행한 다음 요약해야 합니다. 그러면 공정한 비교가 될 것입니다. 그래서 정규화가 없고 테스트 알고리즘을 최적화했습니다. 당연히 더 빠르고 정확할 것입니다(누적 오차가 줄어들기 때문에)
이것을 어떻게 압니까?
비정규화된 가격을 테스터에 입력으로 제출할 수 있고 테스터와 동일하게 작동하기 때문입니다.
결국 가격이 정상화되지 않아도 정상화 없이 확인만 하고
이 경우 정규화는 단일 표준 알고리즘을 의미했으며 적용 후 이 표준의 두 배를 직접 비교할 수 있습니다.
따라서 테스터는 직접 비교하지 않습니다. 그리고 NormalizeDouble , ticksize 또는 다른 방법을 통해 이 작업을 수행합니다. 그러나 확실히 두 배의 직접적인 비교는 아닙니다. 그리고 이것은 완전히 비합리적입니다.
물론, 두 배를 서로 직접 비교할 수 있고 때로는 필요할 수도 있습니다.
예를 들어 최적화 중에 OnTick은 때때로 1조 번 호출됩니다. 행잉 리밋을 실행할지 여부를 이해하기 위해 Staff Tester는 현재 해당 심볼 가격과 리밋 가격을 비교합니다. 각 OnTick 호출 전에 각 스누즈에 대해 이 작업을 수행합니다. 저것들. 이러한 검사는 수십억 번 및 수천억 번 수행됩니다.
그리고 이것은 정규화를 통해 매번 수행됩니다. 그래서 - 이것은 쓸데없는 컴퓨팅 자원 의 끔찍한 낭비입니다. 왜냐하면 가격 및 보류 중인 주문 및 기호는 사전 정규화됩니다. 따라서 서로 직접 비교할 수 있고 또 그래야 합니다.
당연하게도 MQL 맞춤형 테스터는 성능 면에서 기본 일반 테스터보다 더 나은 성과를 거두고 있습니다.
나는 속도를 위해 미친 버전을 확인하기로 결정했다.
그리고 결과는 놀랐습니다.
사전 정규화 된 double의 비교는 double이 epsilon을 통해 또는 int로 변환을 통해 비교되는 경우보다 평균적으로 훨씬 느립니다.
결과:
나는 많은 것이 프로세서의 참신함과 아키텍처에 달려 있고 누군가에게는 결과가 다를 수 있다는 점을 배제하지 않습니다.
솔직히 위협 - 왜 이런 일이 발생하는지 이해조차 되지 않습니다.
컴파일러는 난수의 합으로 최적화할 것이 없는 것 같습니다. 대괄호에서 반올림을 수행할 수 없습니다.
프로세서에서 double을 비교하는 것은 하나의 명령인 것 같습니다.
엡실론 비교 옵션(가장 빠른 옵션)을 사용하면 두 배를 비교하는 연산이 계속 발생하지만, 이 경우에는 3개의 매개변수를 전달하고 1개의 빼기 연산으로 함수를 추가로 호출합니다.
두 개의 이중 비교 연산의 성능은 실제로 변수 자체의 값에 달려 있습니까? 나는 의심한다.
젠장, 이해가 안 돼요. 도와주세요 - 내가 무엇을 고려하지 않았거나 어디에서 실수를 했습니까?