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 ...

[Excluído]  
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 ...