Frage an #define-Experten - Seite 6

 
Igor Makanu:

Wenn Sie die Größe von Arrays im Hauptteil der Schleife ändern, funktioniert die fliegende Optimierung nicht.

Ändern Sie also den Code:

)))) müssen Sie einfach auch den Wert Ihrer Größenvariablen ändern, so dass die genannte erste Methode , die ArraySIze verwendet, von Vorteil ist

 
Alexandr Andreev:

Nun, ich kann IMHO nichts dagegen sagen.

Bei sehr großen Wiederholungen sind meine Siege bei der ersten und zweiten Methode zufällig geworden... Höchstwahrscheinlich hängt dies vom aktuellen CPU-Cache und der Gesamtlast ab.

Meine Frage bezog sich nicht auf die Schleife, sondern darauf, wie sich die Funktion entfaltet. Es ist nur so, dass ArraySize als Beispiel verwendet wurde.

Die Perfektion einer Hochsprache liegt genau dann vor, wenn das bequeme Schreiben ebenso billig ist wie das nicht bequeme, aber von Natur aus billige Schreiben. Schade, dass es nicht immer so ist, und Hilfe mit einem Helfer für Neulinge nicht immer entweder..... gäbe es keine Fragen)))

 
Igor Makanu:

Wenn Sie die Größe von Arrays im Hauptteil der Schleife ändern, funktioniert die fliegende Optimierung nicht.

Ändern Sie also den Code:


es funktioniert nicht

Laufzeitoptimierung hat die Nase vorn

man kann solche einfachen Mashin-Befehle nicht ohne einen Profiler testen, oder man kann in der Schleife schreiben, oder in einem Tester testen, Geschwindigkeit ist dafür wichtig

Ich habe nicht von der Schleife gesprochen, sondern davon, wie der Compiler Funktionen entfaltet..... come on.

Ich überlasse es Ihnen.

 
Alexandr Andreev:

)))) dürfen Sie auch den Wert Ihrer Größenvariablen ändern, so dass die erste Methode , die ArraySIze verwendet, gewinnt.

Ich schrieb oben - solch einfacher Code kann nicht mit einfachen Messungen getestet werden, es gibt viele Faktoren - der Code ist klein - er passt in den Prozessor-Cache, der Code muss im Prozessor gut in parallele Mikro-Befehle in der Prozessor-Pipeline zerlegt werden, d.h. Register werden schnell durch Daten-Prefetching geladen

und vielleicht wird auch rand() irgendwo zwischengespeichert


Ich weiß nicht, wie man ohne Debugger testen kann - zumindest kann man dort die Zeit der Befehlsausführung in Takt sehen

 
Alexandr Andreev:

Dann beweisen Sie mir das Gegenteil.)

Denn in meinem Test sind sie aus irgendeinem Grund identisch.

Ich habe meinen Beitrag geändert.
Es scheint mir, dass ArraySize jetzt schneller ist als die cnt Variable.
Früher war es genau umgekehrt. Vielleicht wirkt sich das Inkrement cnt-- aus, der Schleifenkörper ist anders und wahrscheinlich muss etwas anderes für die Belastung erfunden werden.

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < ArraySize(arr); i++) 
   {
      ArrayResize(arr, sz--); //какая то нагрузка
   }   
   
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:33:22.863 TestScript (USDJPY,M1)  Total time: 451.200 ms


void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   int cnt = ArraySize(arr);
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < cnt; i++) 
   {
      ArrayResize(arr, sz--);
      cnt--;
   }
      
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:56:26.591 TestScript (USDJPY,M1)  Total time: 531.872 ms
 
Roman:

Das ist seltsam.
DieVerwendung von ArraySize(arr) in der Schleifenbedingung zeigt weniger Zeit als die Verwendung der cnt-Variable.
Vorher war es genau umgekehrt. Vielleicht ist es ein Fehler? So sollte es nicht sein.

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

cnt

es für Sie ändern, wie es in der ersten Variante geschieht

 
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 (keine Prüfung), welcher Weg schneller ist. Sehen Sie, wie viele externe Funktionen in der oberen Methode aufgerufen werden

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

als eine Variante des Tests - man kann auch nur verschiedene Arrays in jeden Test einbauen - in meinem Beispiel arr1,arr2...

d.h. tst1_arr1[],tst1_arr2[] .... und tst2_arr1[],tst2_arr2[]


wäre dies ein gerechterer Test.

ich bin weg, sehr ablenkend - imho, praktisch, benutze es

 
Igor Makanu:

Ich weiß nicht, wie man ohne Debugger testen kann - zumindest kann man dort die Befehlsausführungszeit in Taktzyklen sehen

Nun, ja - ohne Debugger geht es nicht. Und in der Zeit dort...

 
Roman:

Das ist seltsam.
DieVerwendung von ArraySize(arr) in der Schleifenbedingung zeigt weniger Zeit als die Verwendung der cnt-Variable.
Vorher war es genau umgekehrt. Vielleicht ist es ein Fehler? So sollte es nicht sein.

Es liegt ein Zufallsergebnis vor. Beim Kompilieren werden Zugriffe auf eine Speicherzelle mit einem Array-Größenwert abgewickelt, während die Array-Größe vorher empfangen und in die Speicherzelle eingefügt wird, wenn das Array gebildet wird, selbst wenn das Array dynamisch ist und Zellen mit einer Array-Größe und einem Variablenwert die gleiche Zugriffszeit haben.

Und nach dem Satz zu urteilen, den Compiler in einem 3-4-jährigen Informatikkurs machen ... im Allgemeinen hoffe ich, dass mich ein hinreichend notwendiges Maß an Framing in einer MCL-Umgebung nicht sehr nervös macht)