Fehler, Irrtümer, Fragen - Seite 2315

 
fxsaber:

Warum ist by_ref langsamer als by_val?

Woraus ergibt sich das?

Wenn der Code derselbe ist

//Test.mqh
        int by_ref(string& var) { return int(var) % 100; }
        int by_val(string  var) { return int(var) % 100; }
//Test.mq5
#include "Test.mqh"
#define  ITERATIONS 1000000
#define  MACRO( X ) \
        { \
                ulong time = GetMicrosecondCount(); \
                for(int i=0; i<ITERATIONS; i++) \
                { \
                        string r = string( rand ); \
                        sum_##X += by_##X(r); \
                } \
                time_##X = GetMicrosecondCount() - time; \
        }
void OnStart()
{
        for ( int i = 0; i < 10; i++ )
                OnStart2( rand());
}
void OnStart2( int rand )
{
        long time_ref, sum_ref = 0;
        long time_val, sum_val = 0;
        MACRO( ref )
        MACRO( val )
        printf( "%+10.3f:%d", (time_ref-time_val)/1000.0, sum_ref-sum_val );
}

so auch das Ergebnis (Unterschied in der Ausführungszeit):

+12.221:0
+5.099:0
+0.149:0
-13.729:0
+14.531:0
-27.429:0
+26.405:0
-0.839:0
+5.400:0
-4.882:0

abwechselnd (+\-) in unbedeutenden Grenzen

 
A100:

Woher kommt sie?

#define  ITERATIONS 1000000

void OnStart()
{
   string Str = "1";
   
   for (int i = 0; i < 10; i++)
     Str += Str;
   
   for (int j = 0; j < 5; j++)
   {
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++){
           string r = string(rand()) + Str;
           sum += by_ref(r);
        }
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_ref", time/1000.0, sum);
     }{
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_val(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_val", time/1000.0, sum);
     }
     
     Print("");
   }
}
//+------------------------------------------------------------------+

int by_ref(string &var){ return int(var) % 100; }
int by_val(string  var){ return int(var) % 100; }


by_ref took 15119.806 milliseconds: sum=-1000000 ll
by_val took 13872.479 milliseconds: sum=-1000000 ll

by_ref took 14433.781 milliseconds: sum=-1000000 ll
by_val took 13817.533 milliseconds: sum=-1000000 ll

by_ref took 13889.424 milliseconds: sum=-1000000 ll
by_val took 14135.603 milliseconds: sum=-1000000 ll

by_ref took 16047.643 milliseconds: sum=-1000000 ll
by_val took 14494.432 milliseconds: sum=-1000000 ll

by_ref took 15542.276 milliseconds: sum=-1000000 ll
by_val took 13843.121 milliseconds: sum=-1000000 ll
 
Nikolai Semko:

Ich wollte die KB mit einer Note versehen, aber es hat nicht funktioniert. Und der Tatsache nach zu urteilen, dass die jüngsten Veröffentlichungen überhaupt keine Noten enthalten, bin ich wohl nicht der Einzige mit diesem Problem.

Ja, es funktioniert nicht.

 
fxsaber:
Meine ref- und val-Schleifen haben denselben Code (der Vergleich ist mehr oder weniger korrekt), aber Ihrer ist anders
 
A100:
In meinen Schleifen haben ref und val denselben Code (der Vergleich ist mehr oder weniger korrekt), während Ihrer anders ist

Ja, anders. Aber die Frage bleibt bestehen. Warum ist val-variant spürbar schneller als ref?

 
fxsaber:

Ja, anders. Aber die Frage bleibt bestehen. Warum ist die val-Variante spürbar schneller als ref?

Vielleicht wird die ref-Variante vom Compiler weniger optimiert - wer weiß.

Meiner Meinung nach sollten beide Varianten nahezu denselben Code kompilieren oder sogar denselben Code vollständig kompilieren, aber der Compiler behandelt die Dinge unterschiedlich

 
TheXpert:

Vielleicht ist die ref-Variante vom Compiler schlechter optimiert - wer weiß.

Mir scheint, dass beide ungefähr den gleichen Code kompilieren sollten oder sogar genau den gleichen, aber der Compiler denkt anders

Die Frage richtete sich eigentlich an die Entwickler, so dass es eine Grundlage für Diskrepanzen bei den Gründen für Diskrepanzen gibt.

Normalerweise versuche ich, alles per Referenz zu übermitteln, um schneller zu sein. Und dies war bei einigen Gebäuden gerechtfertigt. Aber es scheint mir jetzt.

 
Alexey Kozitsyn:

+1. Irgendetwas scheint kaputt zu sein. Bild 1881 x64. Win 10. Beim Start wird die CPU um 20+% (i5 8600k) und der RAM um 650-700mb (keine Erhöhung) belastet.

Der Task-Manager zeigt den Status "Keine Antwort" an.

Und das andere Terminal 1881 (nicht Opening) läuft einwandfrei.

Hinzugefügt:

Schließlich wurde er hochgefahren. Allerdings dauerte das Booten extrem lange - das ist nicht normal. Dann schloss ich das Terminal und öffnete es erneut. Wurde sofort geöffnet. Offenbar gab es ein Problem beim Laden der Daten.

Die Lösung bestand darin, das Terminal neu zu installieren. Ich habe versehentlich den Ordner mit allen Einstellungen und Diagrammen gelöscht. Ich habe alles neu gezeichnet, aber jetzt funktioniert es wie am Schnürchen.
 
reztor:
Die Lösung bestand darin, das Terminal neu zu installieren. Ich habe auch versehentlich den Ordner mit allen Einstellungen und Diagrammen gelöscht) Ich habe alles wieder gezeichnet, aber es funktioniert jetzt wie am Schnürchen.

Dies war nicht notwendig. Sie hätten die Datei news.dat einfach löschen können.

 
TheXpert:

Vielleicht wird die ref-Variante vom Compiler schlechter optimiert - wer weiß?

Meiner Meinung nach sollten beide Optionen annähernd den gleichen Code kompilieren oder sogar komplett den gleichen Code, aber der Compiler zählt auf eine andere Weise

Welcher Zusammenhang besteht zwischen dem endgültigen Code und seiner Ausführungszeit?

Ändern wir zum Beispiel ... so dass die Schleifen absolut identisch werden

#define  ITERATIONS 1000000
void OnStart()
{
   string Str = "1";
   for (int i = 0; i < 10; i++)
     Str += Str;
   for (int j = 0; j < 5; j++)
   {
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_ref(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_ref", time/1000.0, sum);
     }
     {
        ulong time = GetMicrosecondCount();
        ulong sum = 0;
        for(int i=0; i<ITERATIONS; i++)
           sum += by_val(string(rand()) + Str);
        time = GetMicrosecondCount() - time;
        printf("%s took %.3f milliseconds: sum=%dll", "by_val", time/1000.0, sum);
     }    
     Print("");
   }
}
int by_ref(string var){ return int(var) % 100; }
int by_val(string var){ return int(var) % 100; }

Das Ergebnis..:

by_ref dauerte 18354,547 Millisekunden: sum=1865600ll
by_val dauerte 18318.319 Millisekunden: sum=1861628ll

by_ref brauchte 18416.747 Millisekunden: sum=1904488ll
by_val dauerte 18221.978 Millisekunden: sum=1907860ll

by_ref dauerte 18301.009 Millisekunden: sum=1757988ll
by_val dauerte 18545.258 Millisekunden: sum=1949720ll

by_ref dauerte 18373,648 Millisekunden: sum=1867160ll
by_val dauerte 17972,432 Millisekunden: sum=1760308ll

by_ref dauerte 19426,076 Millisekunden: sum=1795564ll
by_val dauerte 19177,485 Millisekunden: sum=1826360ll

ist ungefähr das gleiche... Oder glauben Sie, dass der Compiler in denselben Schleifen unterschiedlichen Code erzeugt hat?

Ich möchte Sie daran erinnern, dass es etwas Ähnliches gab

by_ref dauerte 13889,424 Millisekunden: sum=-1000000ll
by_val dauerte 14135,603 Millisekunden: sum=-1000000ll

und anderen Code... und der Zeitunterschied ist in etwa derselbe, aber der Code und die Funktionen selbst sind genau die gleichen