Declarando variáveis atrás do laço ou dentro do laço? - página 5

 
pivalexander:

Prefiro dividir o código em blocos lógicos e declarar neles as variáveis necessárias para eles, em vez de criar um monte de variáveis no início de uma função, a maioria das quais são necessárias apenas em um bloco, em algum lugar distante

Para variáveis necessárias em apenas um lugar - sim, faz sentido declará-las antes do próprio bloco, especialmente quando o bloco é pequeno. Mas, se o bloco é suficientemente grande e as variáveis são necessárias em outro lugar - eu preferiria declará-las no início da função. Mas é preciso usar o bom senso aqui.

 
pivalexander:

O resultado da execução com um corpo de loop vazio é muito diferente, muito mais rápido

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

O que você mede em microssegundos? .... Você tem certeza de que tem um teste realista?

;)

Aqui está outro teste como este:

#define  N 8

#define    test(M,S,EX,res) {                             \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX;  res }                                             \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string result;
   string s1;  test(N,"1. s1=",s1=(string)tst, result = s1;);
   string s2;  test(N,"2. s2=",s2=(string)tst, result = s2;);
   string s3;  test(N,"3. s3=",s3=(string)tst, result = s3;);
   string s4;  test(N,"4. s4=",s4=(string)tst, result = s4;);
   string s5;  test(N,"5. s5=",s5=(string)tst, result = s5;);

   test(N,"1. q=",string q=(string)tst, result = q;);
   test(N,"2. w=",string w=(string)tst, result = w;);
   test(N,"3. e=",string e=(string)tst, result = e;);
   test(N,"4. r=",string r=(string)tst, result = r;);
   test(N,"5. t=",string t=(string)tst, result = t;);
  }

2019.08.18 12:14:20.765 SpeedTest (EURUSD,H1) 1. s1=: loops=100000000 ms=8156

2019.08.18 12:14:29.127 SpeedTest (EURUSD,H1) 2. s2=: loops=100000000 ms=8359

2019.08.18 12:14:37.353 SpeedTest (EURUSD,H1) 3. s3=: loops=100000000 ms=8235

2019.08.18 12:14:45.464 SpeedTest (EURUSD,H1) 4. s4=: loops=100000000 ms=8109

2019.08.18 12:14:53.557 SpeedTest (EURUSD,H1) 5. s5=: loops=100000000 ms=8094

2019.08.18 12:15:01.446 SpeedTest (EURUSD,H1) 1. q=: loops=100000000 ms=7890

2019.08.18 12:15:09.159 SpeedTest (EURUSD,H1) 2. w=: loops=100000000 ms=7703

2019.08.18 12:15:16.903 SpeedTest (EURUSD,H1) 3. e=: loops=100000000 ms=7750

2019.08.18 12:15:24.716 SpeedTest (EURUSD,H1) 4. r=: loops=100000000 ms=7813

2019.08.18 12:15:32.661 SpeedTest (EURUSD,H1) 5. t=: loops=100000000 ms=7937

 
Igor Makanu:

O que você mede em microssegundos? .... Você tem certeza de que seu teste corresponde à realidade?

   ulong  time_finish = GetMicrosecondCount();
   ulong  res = time_finish - time_start;

É assim que eu meço.

 
pivalexander:

Estou medindo desta forma.

Eu entendo isso, mas você tem que medir pelo menos alguns segundos

Windows não é um sistema em tempo real, não é? E as tarefas de fundo também requerem recursos do Windows, portanto seus testes estão no nível de imprecisão do cronômetro do sistema e dos processos de fundo

imho, um teste de pelo menos 5 segundos é pelo menos alguma informação confiável

 
Igor Makanu:

Eu entendo isso, mas você precisa medir pelo menos alguns segundos

Windows não é um sistema em tempo real, não é? E as tarefas de fundo também requerem recursos do Windows, portanto seus testes estão no nível de imprecisão do cronômetro do sistema e dos processos de fundo

imho, um teste de pelo menos 5 segundos é pelo menos alguma informação confiável

Eu medi vários segundos cada um, o resultado é o mesmo, por que esperar tanto tempo para postar o resultado aqui

 

Em geral, decidi fazer um teste, mas 100% correto, para que nada fosse cortado.

void OnStart()
{
  int count= (int)10 e6;

  { 
    uint t= GetTickCount();
    int sum=0;
        
    for (int i=0; i<count; i++)
    {
       string st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test1, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
  
  {
    uint t = GetTickCount();
    int sum=0;
    string st = "";
    for (int i=0; i<count; i++)
    {
       st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test2, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
}

No modo não otimizado, a segunda variante realmente se revela mais rápida, enquanto no modo otimizado é vice-versa. A segunda variante, entretanto, de alguma forma se torna mais lenta do que era antes da otimização)

 
pivalexander:

Fez medições por alguns segundos de cada vez, o resultado é o mesmo, por que esperar muito tempo para postar o resultado aqui

e várias vezes o mesmo teste deve ser executado, pois há uma alta probabilidade de operações de cache no próximo teste a ser realizado, que pode resultar em 2 testes idênticos com pequenas diferenças - você não vê a diferença de um mesmo teste?

Depende de você, como escrevi acima, não confio em ninguém, nem mesmo no Windows, no processador e em mim mesmo ;)


Alexey Navoykov:

Em geral, decidi fazer um teste, mas 100% correto, de que nada foi cortado.

Enquanto no modo não otimizado a segunda variante é de fato mais rápida, no modo otimizado ela é vice-versa. E a segunda maneira, por alguma razão, torna-se mais lenta do que antes da otimização)

Não é um fato, não há srand() , eu lhe disse que rand() é muito legal, otimizado pelo compilador ;)

E copie o texto do roteiro pelo menos 2 vezes - para que você possa ver o que o compilador rasgou ;)

 
pivalexander:

O que a memória e o processador têm a ver com isso? É sobre otimização, você é um teórico livreiro)

Se você for além dos parênteses em seu raciocínio e entender como um compilador funciona e como sua otimização funciona, você verá que o objetivo de qualquer compilador é reduzir o número de ciclos de execução de código do relógio e reduzir ao máximo os acessos não seqüenciais à memória. Portanto, o resultado da otimização de qualquer compilador, se ele existir, será conhecido por você de antemão sem nenhum teste idiota. É como usar testes para descobrir que 2 + 2 = 4...

E sobre o teórico do livro... Este teórico tem escrito desde 87, começando com EC1020 e ZX Spectrum, escreveu mais de um compilador e contratou mais de 600 programadores para sua empresa...

 
Aleksandr Matveev:

Se você for além dos parênteses em seu raciocínio e entender como o compilador funciona e como sua otimização funciona, você verá que o objetivo de qualquer compilador é reduzir o número de ciclos de execução de código do relógio e reduzir ao máximo os acessos não seqüenciais à memória e, consequentemente, você saberá o resultado da otimização de qualquer compilador, se ele existir, com antecedência, sem nenhum teste idiota. É como usar testes para descobrir que 2 + 2 = 4...

E sobre o teórico do livro... Este teórico trabalha desde 87 quando começou a trabalhar com EU1020 e ZX Spectrum, escreveu vários compiladores próprios e convidou mais de 600 programadores para sua empresa...

Vocês estão ocupados com livros, elogiando-se, mas não disseram nada sobre a essência da questão, apenas dançando em torno da teoria... Se vocês lerem isto, vão entender... Memória e CPU, CPU e memória, a fonte de alimentação também é utilizada ali ...

 
Você sabia que uma corda pode ter um pequeno buffer interno e, para cordas pequenas, os dados podem ir para lá em sua totalidade? Por assim dizer, para acelerar a maioria dos casos triviais. Enquanto brincava com a captura de malloc(), notei que se a corda é menor que cerca de 15 caracteres, o malloc não se mexe em nada. Como seriam seus testes ...
Razão: