Declarando variáveis atrás do laço ou dentro do laço?

 
   string st = "";
   for (int i = 0; i < 1000; i++)
   {
      st = i;
      ...
   }

ou

   for (int i = 0; i < 1000; i++)
   {
      string st = i;
      ...
   }

Existe alguma diferença? dadas todas as otimizações do compilador mql5?

 
pivalexander:

ou

Existe alguma diferença? dadas todas as otimizações do compilador mql5?

Não há diferença na compilação, portanto, sinta-se à vontade para usar a segunda opção.
 

Pessoalmente, eu prefiro a primeira.

Só por precaução. O compilador pode ser suficientemente inteligente para não alocar memória toda vez, mas no primeiro caso eu especifico explicitamente, mas no segundo caso é um resultado implícito do compilador, porque a lógica da linguagem é criar uma variável dentro de um bloco e removê-la na saída do bloco.

E equiparar int a string sem transformação é má prática.

 
pivalexander:

Existe alguma diferença? dadas todas as otimizações do compilador mql5?

Não escute que não há diferença. Use apenas a primeira opção, há uma diferença. No entanto, não estudei o desastroso da mcl.

 
Georgiy Merts:

Pessoalmente, eu prefiro a primeira.

Só por precaução. O compilador pode ser suficientemente inteligente para não alocar memória toda vez, mas no primeiro caso eu especifico explicitamente, mas no segundo caso é um resultado implícito do compilador, pois a lógica da linguagem é criar uma variável dentro de um bloco, e na saída do bloco ela deve ser apagada.

E equiparar int a string sem convertê-lo é má prática.

George está certo, não é garantido.

E obtemos uma deformação da conversão implícita de 'número' para 'cordel'.


E é exatamente assim que nos livramos da indeterminação e das deformações.

for (int i = 0; i < 1000; i++)
   {
      static string st = IntegerToString(i);
      ...
   }
 
Georgiy Merts:

Pessoalmente, eu prefiro a primeira.

Só por precaução. O compilador pode ser inteligente o suficiente para não alocar memória toda vez, mas no primeiro caso eu especifico explicitamente, mas no segundo caso é um resultado implícito do trabalho do compilador

Você está brincando? É uma situação tão trivial para o compilador que não há nada para se falar. Você pode ser tão paranóico sobre isso que só precisa codificar em assembler. Embora até isso já se torne insensato hoje em dia. Você terá que se esforçar muito para bater a otimização dos compiladores modernos.

p.s. Talvez eu estivesse um pouco excitado com a trivialidade no caso do buffer de cordas. Mas é garantido ser salvo em MQL, não apenas dentro do laço, mas até mesmo entre chamadas de função. Este tópico foi discutido aqui mais de uma vez
 

Não os escute, eles lhe dirão muito sobre isso aqui ))

// c++
#include <iostream>
#include <string>
using namespace std;

void* operator new(size_t sz) {
    void *ptr = std::malloc(sz);
    if (ptr)
        return ptr;
    else
        throw std::bad_alloc{};
}


int main() {
        for (uint i = 0;  i < 3;  ++ i) {
                string s;
                char buf[10];
                sprintf(buf, "%u", i);
                s = "sfjhidfsrtea111";
                s += buf;
                cout << s << '\n';
        }
}

Eu compenso o gcc -O3, faço o teste de depuração, defino o ponto de parada do operador novo, recebo três chamadas. O mesmo com o clang.

Nota: se o fio for tirado do laço, recebo uma chamada.

 
Alexey Navoykov:

Você está brincando? É uma situação tão trivial para um compilador que não há nada para falar. Se você é tão paranóico, você pode escrever código puramente em assembler. Mas mesmo isso está se tornando sem sentido hoje em dia. Você terá que se esforçar muito para bater a otimização dos compiladores modernos.

p.s. Talvez eu estivesse um pouco excitado com a trivialidade no caso do buffer de cordas. Mas é garantido ser salvo em MQL, não apenas dentro do laço, mas até mesmo entre chamadas de função. Este tópico foi discutido aqui mais de uma vez

Não, não estou.

Certamente, um compilador normal neste caso deve trazer uma declaração variável dentro de um laço para o exterior.

Eu só acho que você deve sempre confiar no compilador e confiar em si mesmo. É um padrão de compilação que uma variável local é criada quando é declarada e é removida quando o bloco em que foi declarada é abandonado. Portanto, você deve se concentrar neste princípio em primeiro lugar e não esperar que o compilador melhore seu código para você.

Não se trata de eficiência (os compiladores modernos realmente dão código de alta qualidade), mas do esquema de pensamento do programador. Quando olho para as fontes da Kodobase, muitas vezes me pergunto quantos defeitos pequenos e simples, mas potencialmente perigosos, eles contêm. Neste caso, ainda não é muito crítico, o máximo que pode acontecer é que o programa funcione um pouco mais lentamente. Erros reais podem ser muito mais complicados.

 
Vict:

Não os escute, eles lhe dirão muito sobre isso aqui ))

Eu compenso o gcc -O3, faço o teste de depuração, defino o ponto de parada do operador novo, recebo três chamadas. O mesmo com o clang.

Assim, se o fio for tirado do laço, recebo uma chamada.

A essência da otimização é que ela não deve mudar a lógica do algoritmo. É por isso que não pode ser detectado explicitamente. Se houver um ponto de parada lá, é claro que o compilador não tem o direito de cortar esse código. Você supôs que o compilador pode pular sobre o ponto de parada? )

Você pode detectar a otimização somente compilando o código ou medindo seu desempenho, então essa é a primeira coisa que você deve fazer. E acalme-se )

 
Aguardando as medidas)
 
Alexey Navoykov:

O objetivo da otimização é que ela não deve mudar a lógica do algoritmo. É por isso que não pode ser detectado explicitamente. Se houver um ponto de parada lá, o compilador naturalmente não tem o direito de cortar esse código. Você esperava que o compilador pudesse pular sobre o ponto de parada? )

Você pode detectar a otimização somente compilando o código ou medindo seu desempenho, então essa é a primeira coisa que você deve fazer. E acalme-se )

Cara, isso é apenas uma burrice selvagem, o que há para comentar, um completo mal-entendido de como funciona o depurador.

Sobre a velocidade - o gerenciador de memória não é tão burro, e não o fato de que ele irá perguntar ao sistema operacional, pode ser usado em excesso anteriormente alocado. Em geral, use-o como você quiser, depende de você. Mas você não deve convencer os outros disso, pelo menos até fornecer provas concretas, onde elas estão?

Razão: