Erros, bugs, perguntas - página 2315

 
fxsaber:

Porque é o by_ref mais lento que o by_val?

De onde se segue?

Se o código for o mesmo

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

o resultado também o faz (diferença de tempo de execução):

+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

alternando (+\-) dentro de limites insignificantes

 
A100:

De onde é que vem?

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

Queria pôr uma nota no KB e não funcionou. E a julgar pelo facto de as publicações recentes não terem quaisquer notas, parece que não sou o único com este problema.

Sim, não está a funcionar.

 
fxsaber:
Os meus loops de árbitro e val têm o mesmo código (a comparação é mais ou menos correcta), mas o seu é diferente
 
A100:
Nos meus loops ref e val têm o mesmo código (a comparação é mais ou menos correcta), enquanto que o seu é diferente

Sim, diferente. Mas a questão permanece válida. Por que é que a val-variante é visivelmente mais rápida do que a ref?

 
fxsaber:

Sim, diferente. Mas a questão permanece válida. Porque é que a variante val-variante é visivelmente mais rápida do que a ref?

Talvez a variante ref seja menos optimizada pelo compilador - quem sabe.

Na minha opinião, ambas as variantes devem compilar quase o mesmo código ou mesmo completamente o mesmo código, mas o compilador trata as coisas de forma diferente

 
TheXpert:

Talvez a variante ref seja pior optimizada pelo compilador - quem sabe.

Parece-me que ambos deveriam compilar aproximadamente o mesmo código ou mesmo exactamente o mesmo, mas o compilador pensa de forma diferente

A questão foi na realidade dirigida aos promotores, de modo que existe uma base para discrepâncias nas razões das discrepâncias.

Normalmente tento passar tudo por referência de velocidade. E isto foi justificado em algumas construções. Mas parece-me que agora.

 
Alexey Kozitsyn:

+1. Algo parece estar partido. Bild 1881 x64. Ganhar 10. Em cargas de arranque de CPU por 20+% (i5 8600k) e RAM por 650-700mb (sem aumento).

O gestor de tarefas mostra o estado de "Não responder".

E o outro terminal 1881 (não Abertura) funciona bem.

Adicionado:

Acabou por arrancar. Contudo, demorou muito tempo a arrancar - isso não é normal. Depois fechei o terminal e abri-o novamente. Aberto instantaneamente. Aparentemente, houve algum problema com o carregamento de dados.

Resolvido com a reinstalação do terminal. Retirei acidentalmente a pasta com todas as definições e gráficos) desenhei tudo de novo, mas agora funciona como um relógio.
 
reztor:
A solução foi a de reinstalar o terminal. Também apaguei acidentalmente a pasta com todas as definições e gráficos) desenhei tudo novamente, mas agora funciona como um relógio.

Isto não foi necessário. Poderia simplesmente ter apagado o ficheiro news.dat.

 
TheXpert:

Talvez a variante ref seja pior optimizada pelo compilador - quem sabe?

Na minha opinião, ambas as opções devem compilar aproximadamente o mesmo código ou mesmo completamente o mesmo código, mas o compilador conta de uma forma diferente

Qual é a ligação entre o código final e o seu tempo de execução?

Por exemplo, vamos mudar . .. para que os loops se tornem absolutamente idênticos

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

O resultado..:

by_ref levou 18354.547 milissegundos: soma=1865600ll
por_val levou 18318,319 milissegundos: soma=1861628ll

by_ref levou 18416,747 milissegundos: soma=1904488ll
by_val levou 18221.978 milissegundos: soma=1907860ll

by_ref levou 18301.009 milissegundos: soma=1757988ll
por_val levou 18545,258 milissegundos: soma=1949720ll

by_ref levou 18373,648 milissegundos: soma=1867160ll
by_val levou 17972.432 milissegundos: soma=1760308ll

by_ref levou 19426.076 milissegundos: soma=1795564ll
by_val levou 19177,485 milissegundos: soma=1826360ll

é mais ou menos o mesmo... Ou pensa que o compilador criou códigos diferentes nos mesmos loops?

Deixem-me lembrar-vos - havia algo parecido com isto

by_ref levou 13889,424 milissegundos: soma=-1000000ll
by_val levou 14135,603 milissegundos: soma=-1000000ll

e código diferente... e há aproximadamente a mesma diferença no tempo, mas o código e as próprias funções são exactamente as mesmas