Errori, bug, domande - pagina 2315

 
fxsaber:

Perché by_ref è più lento di by_val?

Da dove viene?

Se il codice è lo stesso

//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 );
}

così come il risultato (differenza di tempo di esecuzione):

+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

alternato (+\-) entro limiti insignificanti

 
A100:

Da dove viene?

#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:

Volevo mettere un voto sulla KB e non ha funzionato. E a giudicare dal fatto che le pubblicazioni recenti non hanno nessun voto, sembra che io non sia l'unico con questo problema.

Sì, non funziona.

 
fxsaber:
I miei cicli ref e val hanno lo stesso codice (il confronto è più o meno corretto), ma il tuo è diverso
 
A100:
Nei miei cicli ref e val hanno lo stesso codice (il confronto è più o meno corretto), mentre il tuo è diverso

Sì, diverso. Ma la domanda rimane valida. Perché val-variant è notevolmente più veloce di ref?

 
fxsaber:

Sì, diverso. Ma la domanda rimane valida. Perché la val-variante è notevolmente più veloce di ref?

Forse la variante ref è meno ottimizzata dal compilatore - chi lo sa.

A mio avviso, entrambe le varianti dovrebbero compilare quasi lo stesso codice o anche completamente lo stesso codice, ma il compilatore gestisce le cose in modo diverso

 
TheXpert:

Forse la variante ref è ottimizzata peggio dal compilatore - chi lo sa.

Mi sembra che entrambi dovrebbero compilare più o meno lo stesso codice o addirittura esattamente lo stesso, ma il compilatore pensa diversamente

La domanda era in realtà destinata agli sviluppatori, in modo che ci sia una base per le discrepanze nei motivi delle discrepanze.

Di solito cerco di passare tutto per riferimento per la velocità. E questo era giustificato in alcune costruzioni. Ma ora mi sembra.

 
Alexey Kozitsyn:

+1. Qualcosa sembra essere rotto. Bild 1881 x64. Win 10. All'avvio carica la CPU del 20+% (i5 8600k) e la RAM di 650-700mb (nessun aumento).

Il Task Manager mostra lo stato "Non risponde".

E l'altro terminale 1881 (non Opening) funziona bene.

Aggiunto:

Alla fine si è avviato. Tuttavia ci è voluto molto tempo per l'avvio - questo non è normale. Poi ho chiuso il terminale e l'ho riaperto. Aperto all'istante. Apparentemente c'è stato qualche problema con il caricamento dei dati.

La soluzione era reinstallare il terminale. Ho accidentalmente tolto la cartella con tutte le impostazioni e i grafici) ho ridisegnato tutto, ma ora funziona come un orologio.
 
reztor:
La soluzione era reinstallare il terminale. Ho anche cancellato accidentalmente la cartella con tutte le impostazioni e i grafici) Ho disegnato tutto di nuovo, ma ora funziona come un orologio.

Questo non era necessario. Avresti potuto semplicemente cancellare il file news.dat.

 
TheXpert:

forse la variante ref è ottimizzata peggio dal compilatore - chi lo sa?

A mio avviso, entrambe le opzioni dovrebbero compilare approssimativamente lo stesso codice o anche completamente lo stesso codice, ma il compilatore conta in modo diverso

Qual è il legame tra il codice finale e il suo tempo di esecuzione?

Per esempio, cambiamo .. . in modo che i cicli diventino assolutamente identici

#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; }

Il risultato..:

by_ref ha impiegato 18354,547 millisecondi: sum=1865600ll
by_val ha impiegato 18318.319 millisecondi: sum=1861628ll

by_ref ha impiegato 18416.747 millisecondi: sum=1904488ll
by_val ha impiegato 18221.978 millisecondi: sum=1907860ll

by_ref ha impiegato 18301.009 millisecondi: sum=1757988ll
by_val ha impiegato 18545.258 millisecondi: sum=1949720ll

by_ref ha impiegato 18373.648 millisecondi: sum=1867160ll
by_val ha impiegato 17972.432 millisecondi: sum=1760308ll

by_ref ha impiegato 19426.076 millisecondi: sum=1795564ll
by_val ha impiegato 19177.485 millisecondi: sum=1826360ll

è circa lo stesso... O pensate che il compilatore abbia creato un codice diverso negli stessi cicli?

Lasciate che vi ricordi che c' era qualcosa del genere

by_ref ha impiegato 13889.424 millisecondi: sum=-1000000ll
by_val ha impiegato 14135,603 millisecondi: sum=-1000000ll

e codice diverso... e c'è circa la stessa differenza di tempo, ma il codice e le funzioni stesse sono esattamente le stesse