Frage an #define-Experten - Seite 7

 
Alexandr Andreev:

Sie haben in Ihrem Code nichts durcheinander gebracht, wer wird den Wert für Sie ändern?

wie in der ersten Version.

Ja, diesen Punkt habe ich übersehen. Ich habe meinen Beitrag korrigiert.

 
Valeriy Yastremskiy:

Das ist ein Zufallsergebnis. Bei der Kompilierung wird der Zugriff auf eine Speicherzelle mit einem Wert für die Array-Größe abgewickelt, und die Array-Größe wird im Voraus ermittelt und in der Speicherzelle platziert, wenn das Array gebildet wird, selbst wenn das Array dynamisch ist, und Zellen mit einer Array-Größe und mit einem variablen Wert haben die gleiche Zugriffszeit.

Und nach dem Satz zu urteilen, den Compiler in einem 3-4-jährigen Informatikkurs machen ... im Allgemeinen hoffe ich, dass eine ausreichende Personalausstattung mich in der MCL-Umgebung nicht sehr nervös macht)

Glauben Sie mir, der durchschnittliche Student in der Regel FIVT ist nur Null mit plus), da es Null Erfahrung, und Wissen ohne Erfahrung geht schnell nirgendwo (vergessen), und ihre Beispiele sind sehr seltsam, wird es Jahre dauern, bis der Schüler versteht, wo und wie sie verwendet werden können. Dies ist der Fall, wenn Sie ihn mit einem erfahrenen Programmierer vergleichen.

 
Alexandr Andreev:

Glauben Sie mir, der durchschnittliche FIVT-Schüler ist in der Regel eine Null plus), denn es gibt keine Erfahrung, und Wissen ohne Erfahrung geht schnell ins Leere (wird vergessen), und ihre Beispiele sind sehr seltsam, es wird Jahre dauern, bevor der Schüler versteht, wo und wie sie verwendet werden können. Dies ist der Fall, wenn Sie ihn mit einem erfahrenen Programmierer vergleichen.

Das ist verständlich. Ich verstehe nicht, warum man unterrichten muss, wie man einen Compiler erstellt. Es ist klar, dass eine Sprache eine Klasse ist, aber nicht jeder Vogel kann a priori fliegen. Nun, wie ich bereits oben erwähnt habe, sind Fehler, Bugs und Fragen auch für die Frage der Optimierung der Kompilierung im laufenden Betrieb relevant.

 

Hier geht es um Definitionen, nicht um Schleifen ))

Aber ich verstehe immer noch nicht, ob es sinnvoll ist, Code zu definieren, zum Beispiel benutzerdefinierte Funktionen.
In der Hoffnung, dass nicht mehr benötigter Code in der ausführbaren Datei schneller ausgeführt wird.
Oder handelt es sich um ein Missverständnis? Denn die Ersetzung ist nur eine Aktion vor der Kompilierung, und sie ist nur sinnvoll, um die Erstellung zu beschleunigen.

 
Roman:

Hier geht es um Definitionen, nicht um Schleifen ))

Aber ich verstehe immer noch nicht, ob es sinnvoll ist, Code zu definieren, zum Beispiel benutzerdefinierte Funktionen.
In der Hoffnung, dass nicht mehr benötigter Code in der ausführbaren Datei schneller ausgeführt wird.
Oder handelt es sich um ein Missverständnis? Denn die Ersetzung ist nur eine Aktion vor der Kompilierung, und es ist nur logisch, die Erstellung zu beschleunigen.

Ich habe Ihnen gerade ein Beispiel gezeigt, bei dem 3 externe Funktionen verwendet werden... gegen seine ungefaltete Form. Es wird also keine Beschleunigung geben.

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Frage an #define-Experten

Alexandr Andreev, 2020.11.02 19:49

void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

500p Frage (ohne Überprüfung), welcher Weg schneller ist. Sehen Sie, wie viele externe Funktionen in der oberen Methode aufgerufen werden


Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 
Alexandr Andreev:

Ich habe Ihnen gerade ein Beispiel gezeigt, bei dem 3 externe Funktionen verwendet werden... gegen seine ungefaltete Form. Es wird also keine Beschleunigung geben.


Ich verstehe. Dann hallo an fxsaber. Er ist ein Fan der Defundierung von allem.


Alexandr Andreev:

Beweisen Sie mir das Gegenteil)

denn in meinem Test sind sie aus irgendeinem Grund identisch.

Wie für ArraySize() und Variable. Ich werde dennoch auf diese Frage zurückkommen.
Im Test habe ich folgende Änderungen vorgenommen. Die Schleife zählt die Anzahl der PIs.
Im ersten Beispiel verwendet die Bedingung der Schleife ArraySize().
Im zweiten Beispiel wird die Variable num_steps verwendet.
Es gibt einen Unterschied.

ArraySize() Funktion

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<ArraySize(arr); i++)
    {
       x = (i + .5) * step;
       sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Drei Durchläufe des Drehbuchs.

2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  Total time to calculate PI was 4049.179 ms
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  Total time to calculate PI was 4183.364 ms
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  Total time to calculate PI was 4034.098 ms
        


Variable num_steps.

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<num_steps; i++)
    {
        x = (i + .5) * step;
        sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Drei Durchläufe des Drehbuchs.

2020.11.03 00:08:09.269 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  Total time to calculate PI was 3955.325 ms
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  Total time to calculate PI was 3950.568 ms
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  Total time to calculate PI was 3927.110 ms
        
 
Roman:

Ich verstehe. Dann hallo an fxsaber. Ein Fan davon, alles in einer Reihe zu definieren.

Wie für ArraySize() und die Variable. Ich werde trotzdem auf diese Frage zurückkommen.
Hier ist der Test, den ich geändert habe. Die Schleife zählt die Anzahl der PIs.
Im ersten Beispiel verwendet die Bedingung der SchleifeArraySize().
Im zweiten Beispiel
wirddie Variable num_steps verwendet.
Es gibt einen Unterschied.

ArraySize() Funktion

Drei Durchläufe des Drehbuchs.


Variable num_steps.

Drei Durchläufe des Drehbuchs.

Bei diesen Berechnungen gibt es keinen eindeutigen Unterschied. Ich habe das alles in einen Code gepackt und die Ergebnisse sind unterschiedlich, in einem Fall gewinnt die erste Variante

)) hat jedes Array in µl eine Variable, die für die aktuelle Größe des Arrays zuständig ist, also in den meisten Sprachen.

Die Funktion ArraySize weist den Compiler an, den Wert dieser Variablen zurückzugeben, d.h. sie ersetzt diese Variable anstelle dieser Funktion. Da µl-Arrays nicht referenziert werden können, bezieht sich der Zeiger explizit auf diese Variable, direkt auf die Krokettchenadresse im Speicher. Technisch gesehen handelt es sich bei all diesen Tests um einen Versuch, zwei regelmäßige Variablen zu vergleichen. Dies ist die Eigenschaft der Entfaltung von Funktionen, in meinem Beispiel verzeihen 4 Funktionen 0 Funktionen, von denen 3 direkt im Schleifenkörper sind, d.h. es gibt einen Vergleich von 40000000000 Funktionsaufrufen gegenüber keinem. Und wir sehen einen impliziten Unterschied, der zu klein ist, um bemerkt zu werden - weil er Code in die ausführbare Datei einfügt.... wir vergleichen das Gleiche.

Und all diese Berechnungen - je komplizierter sie sind, desto weniger Sinn machen sie.

Es ist einfacher, ein Beispiel zu geben, in dem wir in einem Fall hundert Funktionen aufrufen, Funktionen innerhalb von Funktionen... Und im anderen Fall, all dies in erweiterter Form - und es wird keinen Unterschied geben. Da ArraySize(mas)== mas[].Größe

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 

Obwohl das Pi-Beispiel aus irgendeinem Grund einen Unterschied ..... durch die Überschwingungsfrequenz aufweist (Red.), handelt es sich dabei um eine rein zufällige Überschwingung

und es entspricht 1ms pro 1 Milliarde Ausgänge, obwohl dies nicht explizit versucht wird, wenn man die Variablen miteinander vergleicht und die Streuung noch größer wird))


 
Alexandr Andreev:

Bei diesen Berechnungen gibt es keinen klaren Unterschied. Geben Sie alles in einen Code ein, und die Ergebnisse sind unterschiedlich, in einigen Fällen gewinnt die erste Option

)) Jedes Array in µl hat eine Variable, die für die aktuelle Array-Größe verantwortlich ist, also in den meisten Sprachen.

Die Funktion ArraySize weist den Compiler an, den Wert dieser Variablen zurückzugeben, d.h. sie ersetzt diese Variable anstelle dieser Funktion. Da µl-Arrays nicht referenziert werden können, bezieht sich der Zeiger explizit auf diese Variable, direkt auf die Krokettchenadresse im Speicher. Technisch gesehen handelt es sich bei all diesen Tests um einen Versuch, zwei regelmäßige Variablen zu vergleichen. Dies ist die Eigenschaft der Entfaltung von Funktionen, in meinem Beispiel verzeihen 4 Funktionen 0 Funktionen, von denen 3 direkt im Schleifenkörper sind, d.h. es gibt einen Vergleich von 40000000000 Funktionsaufrufen gegenüber keinem. Und wir sehen einen impliziten Unterschied, der zu klein ist, um bemerkt zu werden - weil er Code in die ausführbare Datei einfügt.... wir vergleichen das Gleiche.

Und all diese Berechnungen - je komplizierter sie sind, desto weniger Sinn machen sie.

Es ist einfacher, ein Beispiel zu geben, bei dem wir in einem Fall hundert Funktionen aufrufen, Funktionen innerhalb von Funktionen... Und im anderen Fall, all dies in erweiterter Form - und es wird keinen Unterschied geben. Da ArraySize(mas)== mas[].Größe

Es spielt keine Rolle, was im Schleifenkörper ausgeführt wird. Dies ist nur eine Belastung für den Test.
In den Beispielen wird die Referenz auf eine Funktion oder Variable in der Schleifenbedingung verglichen.

Ich bin kein Assembler, aber ich denke, dass es aus der Sicht der Assembler-Anweisungen nicht dasselbe ist.
Und wenn sie auch noch in einer Klasse verpackt ist, ist das sicher nicht dasselbe.

Eine Funktion hat eine zusätzliche Anweisung, um einen Wert aus einer Speicherzelle abzurufen, d.h. die Funktion ruft die Speicherzelle für einen Wert auf und gibt erst dann das Ergebnis zurück.
Eine Variable hat bereits diesen Wert, die Variable verweist nirgendwo hin, sie gibt das Ergebnis sofort zurück.

 
Roman:

Es spielt keine Rolle, was im Körper des Zyklus durchgeführt wird. Es ist nur eine Belastung für den Test.
In den Beispielen wird der Verweis auf eine Funktion oder Variable in der Schleifenbedingung verglichen.

Ich bin kein Assembler-Experte, aber ich denke, vom Standpunkt der Assembler-Anweisungen aus ist es nicht dasselbe.
Und wenn sie auch noch in einer Klasse verpackt ist, ist das sicher nicht dasselbe.

Eine Funktion hat eine zusätzliche Anweisung, um einen Wert aus einer Speicherzelle abzurufen, d.h. die Funktion ruft die Speicherzelle für einen Wert auf und gibt erst dann das Ergebnis zurück.
Eine Variable hat diesen Wert bereits, die Variable verweist nirgendwo hin, sie gibt das Ergebnis sofort zurück.

) Nun, so funktioniert das nicht)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int mas[];
   int mas1[300];
   int mas2[300];
   int mas3[300];
   int mas4[300];
   int mas5[300];
   int mas6[300];
   int z=300;
   int size=100000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100; 
   int t=0;
   int tr=0; 
   MathSrand(10);
    int num_steps=ArraySize(mas);
    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
     int v=size;
    ulong t1 = GetMicrosecondCount();
     
    
  // for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); i++)
        { 
        r2+=ArraySize(mas);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2=r2/10;
        }

     }  
   ulong t2=GetMicrosecondCount();
   //for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<v; i++)
        { 
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1=r1/10;
        }
     }
   
   int pi2 = sum*step;
   ulong t3=GetMicrosecondCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",pi," ",pi2);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Fast bei jedem Lauf wechselt der Führende

die längste ist die Division)))