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

 

Desculpem pessoal, a otimização foi desligada nas configurações do projeto

Código:

   CStopWatch sw; // Секундомер, для замера времени
   
   sw.Start();
   for (int i = 0; i < 10000000; i++)
   {
      string st = (string)i;
   }
   pr("Test1, время выполнения: " + sw.Stop());

   sw.Start();
   string st = "";
   for (int i = 0; i < 10000000; i++)
   {
      st = (string)i;
   }
   pr("Test2, Время выполнения: " + sw.Stop());


Inoptimizado

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

Com otimização

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

Com a otimização sim, é o oposto, eu verifiquei muitas vezes

 
Aleksandr Matveev:

Você deve aprender o básico primeiro e depois provar seu ponto de vista. Você entenderia o resultado sem nenhum teste, se você tivesse lido pelo menos um livro sobre operação de CPU e memória. Eu lhe ofereci a mais engenhosa e se você quiser avançar um pouco na programação, com certeza vai lê-la.

O que a memória e a CPU têm a ver com isso? É uma questão de otimização, você faz reservas teóricas).

 
Igor Makanu:

não é estranho, você precisa ser capaz de testar os operadores e operações mais simples na MQL - por que eu adicionaria srand(GetTickCount()) ao meu teste? ?

;)

A propósito, veja com atenção, o resultado em seu loop não é levado em conta de forma alguma, o que significa que pode ser facilmente cortado pelo compilador.

 
Alexey Navoykov:

A propósito, olhei atentamente, o resultado em seu loop não é levado em conta de forma alguma, de modo que o compilador pode facilmente cortá-lo.

Removido até mesmo rand() - seu compilador o enfileira perfeitamente, fez tal teste:

#define  N 8

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

   test(N,"1. q=rand()",string q=(string)tst);
   test(N,"2. q=rand()",string q=(string)tst);
   test(N,"3. q=rand()",string q=(string)tst);
   test(N,"4. q=rand()",string q=(string)tst);
   test(N,"5. q=rand()",string q=(string)tst);
  }
//+------------------------------------------------------------------+

2019.08.18 11:55:41.457 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=100000000 ms=7672

2019.08.18 11:55:49.085 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=100000000 ms=7625

2019.08.18 11:55:56.796 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=100000000 ms=7719

2019.08.18 11:56:04.495 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=100000000 ms=7703

2019.08.18 11:56:12.113 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=100000000 ms=7610

2019.08.18 11:56:17.695 SpeedTest (EURUSD,H1) 1. q=rand(): loops=100000000 ms=5578

2019.08.18 11:56:23.362 SpeedTest (EURUSD,H1) 2. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:28.970 SpeedTest (EURUSD,H1) 3. q=rand(): loops=100000000 ms=5609

2019.08.18 11:56:34.637 SpeedTest (EURUSD,H1) 4. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:40.277 SpeedTest (EURUSD,H1) 5. q=rand(): loops=100000000 ms=5640


 
Alexey Navoykov:

Portanto, se você quer "fazer bem", então vá até a montadora. Se você precisa controlar tudo você mesmo... Afinal de contas, o caso que você acabou de descrever não é nada. Há coisas muito mais complicadas. O OOP é definitivamente contra-indicado para você. Você não saberá se o compilador degenerou um determinado método virtual em uma chamada regular ou aparou uma verificação de ponteiro desnecessária... O que você pode fazer em um MQL gerenciado com tal paranóia? )

E afinar o código para as peculiaridades do compilador (e imaginárias, por exemplo), em detrimento da correção e confiabilidade do código, obviamente não é o que um bom programador deve fazer. E aqui estamos falando de incorreção de código. A variável deve ser declarada diretamente no bloco em que é usada.

Ha ha ha ha... Alexey, você afirma (vamos ser "você") que "OOP é definitivamente contra-indicado" a um dos principais adeptos do OOP no fórum.

O código não deve ser ajustado para as peculiaridades do compilador, mas para as peculiaridades do pensamento OWN. Neste caso, a declaração de uma variável dentro de um loop em teoria reduz a eficiência. Porque, de acordo com as convenções, a variável deve ser criada cada vez e destruída cada vez.

Não é nem mesmo a questão da eficiência. Código sólido é o código, que é transparente, claro e fácil de modificar e manter.

Pessoalmente, não gosto de ter muitas variáveis espalhadas por todo o programa e ter que procurar cada vez que uma determinada variável é criada. Portanto, se possível, tento declarar variáveis no início da função, todas juntas - apenas para ver onde elas são criadas e entender quando serão apagadas.

Neste caso, o exemplo é apenas muito curto. Quando há dezenas de linhas e um monte de funções aninhadas entre a criação de uma variável e seu uso - para mim, é muito mais confiável quando a variável é declarada fora do bloco, com antecedência.

 
pivalexander:

Desculpem pessoal, a otimização foi desligada nas configurações do projeto

Código:


Inoptimizado

Com otimização

Com a otimização, sim, é o oposto, já o verifiquei muitas vezes.

Em seu exemplo, todo o corpo do loop poderia ter sido cortado com otimização.

 

De modo geral, tudo se reúne como esperado, que não há necessidade de fazer disparates, procurando problemas inexistentes e criando problemas reais.

Se você tem comichão e pensa que é um hacker legal, escreva em assembler, ou então fique de lado e deixe o compilador fazer seu trabalho.

 
Aleksandr Matveev:

Neste exemplo, todo o seu corpo de laço poderia ter sido cortado com otimização.

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

Без оптимизации:
Test1, время выполнения: 0.027539 сек.

С оптимизацией:
Test1, время выполнения: 0.005448 сек.
 
Alexey Navoykov:

De modo geral, tudo se reúne como esperado, que não há necessidade de fazer disparates, procurando problemas inexistentes e criando problemas reais.

Se você tem comichão e acha que é um hacker legal, escreva em assembler. Caso contrário, simplesmente fique de lado e deixe o compilador fazer seu trabalho.

O problema principal é precisamente que eu não me considero um coolhacker. É por isso que as variáveis, em minha opinião, devem ser declaradas fora do loop. E melhor - no início da função, tudo de uma só vez.

E apenas os koolhousers podem declarar variáveis conforme necessário, dentro do código.

 
Georgiy Merts:

O problema principal é precisamente que eu não me considero um coolhacker. É por isso que as variáveis, em minha opinião, devem ser declaradas fora do loop. E de preferência no início da função, tudo de uma só vez.

Os Koolhackers podem declarar variáveis conforme necessário dentro do código.

Prefiro quebrar meu código em blocos lógicos e declarar variáveis necessárias para eles nesses blocos 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