Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 116

 
Ilya Malev:

(müde) Wenn das das Problem wäre, würde die Fehlermeldung "'k' - redefinition; different type modifiers" auftauchen, aber sie ist nicht auf dem Screenshot zu sehen. Der Compiler kümmert sich also nicht darum, und das ist auch nicht das Problem.

Sieh an, sieh an...

 
Alexey Navoykov:

Sieh an, sieh an...

Versuchen Sie doch, es selbst zu kompilieren. Wenn Sie nicht zu faul sind, Beiträge zu diesem Thema im Forum zu schreiben, sollten Sie auch zu faul sein, sie in einen Editor einzugeben und F7 zu drücken. Es geht viel schneller.

 

Schneller Weg zur Berechnung des binären Logarithmus einer ganzen Zahl. 3-5 mal schneller als MathLog.

int log2(ulong n)
{
  if (n==0) return -1;
  
  #define  S(k) if (n >= (ulong(1)<<k)) { i += k;  n >>= k; }
  
  int i=0;  S(32);  S(16);  S(8);  S(4);  S(2);  S(1);  return i;
  
  #undef  S
}
 
Wird ein in MQL5 geschriebener EA auf einem MT4-Terminal funktionieren? Ich habe irgendwo gelesen, dass es funktionieren wird.
 
Alexey Navoykov:

Schnelle Methode zur Berechnung des binären Logarithmus einer ganzen Zahl. 3-5 mal schneller als MathLog.

Ich verwende eine Funktion wie diese (reiner Schamanismus, aber es funktioniert):

static const uint ulLogTable[64] = 
{
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63 
};


uint _FastLog2(ulong ulInput)
{
   ulInput |= ulInput >> 1;
   ulInput |= ulInput >> 2;
   ulInput |= ulInput >> 4;
   ulInput |= ulInput >> 8;
   ulInput |= ulInput >> 16;
   ulInput |= ulInput >> 32;
  
   return(ulLogTable[(uint)((ulInput * 0x03f6eaf2cd271461) >> 58)]);
};

Beide Funktionen liefern die richtige Antwort, ich habe keine Fehler gefunden.

Es ist interessant, die Arbeitsgeschwindigkeit zu vergleichen. Meine Version hat etwas weniger Verschiebe- und Additionsoperationen, dafür aber eine Multiplikation am Ende. Alexey's Version hat etwas mehr Verschiebe- und Additionsoperationen, aber keine Multiplikation. Warum ist es schneller?

 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von Neulingen zu MQL4, Hilfe und Diskussion über Algorithmen und Codes" verschoben.
 
Kommentare, die sich nicht auf dieses Thema beziehen, wurden nach "Fragen von Neulingen zu MQL4, Hilfe und Diskussion über Algorithmen und Codes" verschoben.
 
Georgiy Merts:

Meine Version hat etwas weniger Verschiebe- und Additionsoperationen, aber keine Multiplikation. Alexey's Version hat etwas mehr Verschiebe- und Additionsoperationen, aber keine Multiplikation. Warum ist es schneller?

Ich habe maximal 6 Verschiebe- und Additionsoperationen (binäre Suche).Shift (ulong)1<<k zählt nicht, weil es eine Konstante ist. Das Einzige ist, dass wir auch den Zustand überprüfen. Aber es sind immer 6 Operationen, plus Multiplikation, plus eine weitere Verschiebung und Zugriff auf das verwaltete Array (d.h. Indexprüfung). Ihre Version wird also offensichtlich langsamer sein :).

Und Ihre Version sieht natürlich geheimnisvoll aus.)

p.s. Ich habe eine Vermutung, dass, wenn mein Code in eine Kette von Vergleichen über if-else abgewickelt werden könnte, die alle arithmetischen Operationen loswerden, würde es die Dinge enorm beschleunigen. Aber es wäre ein großes Durcheinander von Code. Wenn man nur Rekursion in Makros verwenden könnte...

 
Georgiy Merts:

Es ist interessant, die Geschwindigkeit zu vergleichen.

Die log2-Variante ist schneller.

#property strict
#define    test(M,S,EX)        {uint mss=GetTickCount();uint nn=(uint)pow(10,M);for(uint t12=0;t12<nn;t12++){EX;} \
                                printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}

int log2(ulong n){
  if (n==0) return -1;
  #define  S(k) if (n >= (ulong(1)<<k)) { i += k;  n >>= k; }
  int i=0;  S(32);  S(16);  S(8);  S(4);  S(2);  S(1);  return i;
  #undef  S}


static const uint ulLogTable[64] = {
0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61,
51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62,
57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56,
45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, 63 };

uint _FastLog2(ulong ulInput){
   ulInput |= ulInput >> 1;
   ulInput |= ulInput >> 2;
   ulInput |= ulInput >> 4;
   ulInput |= ulInput >> 8;
   ulInput |= ulInput >> 16;
   ulInput |= ulInput >> 32;  
   return(ulLogTable[(uint)((ulInput * 0x03f6eaf2cd271461) >> 58)]);};

void OnStart(){
  srand(GetTickCount());
  ulong n,n1;
  test(8,"MathLog",n=rand()*rand();n1=ulong(MathLog(n)/MathLog(2)))
  test(8,"log2",n=rand()*rand();n1=log2(n);)
  test(8,"_FastLog2",n=rand()*rand();n1=_FastLog2(n))}


 
Ilya Malev:

Die Option log2 ist also schneller.


Ich hab's.

Ich ersetze meine Funktion.