¿Declaración de variables detrás del bucle o dentro del bucle?

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

o

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

¿Hay alguna diferencia? teniendo en cuenta todas las optimizaciones del compilador mql5?

 
pivalexander:

o

¿Hay alguna diferencia? teniendo en cuenta todas las optimizaciones del compilador mql5?

No hay ninguna diferencia en la compilación, así que no dude en utilizar la segunda opción.
 

Personalmente, prefiero lo primero.

Por si acaso. El compilador puede ser lo suficientemente inteligente como para no asignar memoria cada vez, pero en el primer caso lo especifico explícitamente, pero en el segundo caso es un resultado implícito del compilador, porque la lógica del lenguaje es crear una variable dentro de un bloque y eliminarla al salir del bloque.

Y equiparar int a string sin transformación es una mala práctica.

 
pivalexander:

¿Hay alguna diferencia? teniendo en cuenta todas las optimizaciones del compilador mql5?

No escuches que no hay diferencia. Utilice sólo la primera opción, hay una diferencia. Sin embargo, no he estudiado el disassm de mcl.

 
Georgiy Merts:

Personalmente, prefiero lo primero.

Por si acaso. El compilador puede ser lo suficientemente inteligente como para no asignar memoria cada vez, pero en el primer caso lo especifico explícitamente, pero en el segundo caso es un resultado implícito del compilador, porque la lógica del lenguaje es crear una variable dentro de un bloque, y al salir del bloque debe ser borrada.

Y equiparar int a string sin convertirlo es una mala práctica.

George tiene razón, no está garantizado.

Y obtenemos una deformación de la conversión implícita de 'número' a 'cadena'.


Y así es exactamente como nos libramos de la indeterminación y la deformación.

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

Personalmente, prefiero lo primero.

Por si acaso. El compilador puede ser lo suficientemente inteligente como para no asignar memoria cada vez, pero en el primer caso lo especifico explícitamente, pero en el segundo caso es un resultado implícito del trabajo del compilador

¿Bromeas? Es una situación tan trivial para el compilador que no hay nada que hablar. Es posible que estés tan paranoico al respecto que sólo necesites codificar en ensamblador. Aunque incluso eso ya carece de sentido hoy en día. Tendrás que esforzarte para superar la optimización de los compiladores modernos.

p.d. Tal vez me haya entusiasmado un poco con la trivialidad aquí porque estoy hablando del buffer de cadenas. Pero está garantizado que se guarda en MQL, no sólo dentro del bucle, sino incluso entre las llamadas a funciones. Este tema se discutió aquí más de una vez
 

No les hagas caso, aquí te van a contar muchas cosas ))

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

Compilo gcc -O3, lo ejecuto bajo el depurador, pongo punto de interrupción en el operador new, obtengo tres llamadas. Lo mismo con clang.

Nota: si se saca la cadena del bucle, recibo una llamada.

 
Alexey Navoykov:

¿Bromeas? Es una situación tan trivial para un compilador que no hay nada que hablar. Si eres tan paranoico, puedes escribir el código puramente en ensamblador. Pero incluso eso se está convirtiendo en algo sin sentido hoy en día. Tendrás que esforzarte para superar la optimización de los compiladores modernos.

p.d. Tal vez me haya entusiasmado un poco con la trivialidad en el caso del buffer de cadenas. Pero está garantizado que se guarda en MQL, no sólo dentro del bucle, sino incluso entre las llamadas a funciones. Este tema se discutió aquí más de una vez

No, no lo estoy.

Ciertamente, un compilador normal en este caso debería llevar la declaración de una variable dentro de un bucle al exterior.

Creo que siempre hay que confiar en el compilador y en uno mismo. Es un estándar del compilador que una variable local se crea cuando se declara y se elimina cuando se sale del bloque en el que se declaró. Por lo tanto, debes centrarte en este principio en primer lugar y no esperar a que el compilador mejore tu código por ti.

No se trata de la eficiencia (los compiladores modernos realmente dan un código de muy alta calidad), sino del esquema de pensamiento del programador. Cuando miro las fuentes de Kodobase, a menudo me pregunto cuántos defectos pequeños y simples pero potencialmente peligrosos contienen. En este caso no es muy crítico todavía, lo máximo que puede pasar es que el programa funcione un poco más lento. Los errores reales pueden ser mucho más complicados.

 
Vict:

No les hagas caso, aquí te van a contar muchas cosas ))

Compilo gcc -O3, lo ejecuto bajo el depurador, pongo punto de interrupción en el operador new, obtengo tres llamadas. Lo mismo con clang.

Por lo tanto, si la cadena es sacada del bucle, recibo una llamada.

No podría haber hecho otra cosa porque tú mismo has interferido en la optimización con puntos de ruptura. La esencia de la optimización es que no debe cambiar la lógica del algoritmo. Por eso no se puede detectar explícitamente. Si hay un punto de interrup ción allí, por supuesto que el compilador no tiene derecho a cortar este código. ¿Supones que el compilador puede saltar el punto de interrupción? )

Sólo se puede detectar la optimización compilando el código o midiendo su rendimiento, así que eso es lo primero que hay que hacer. Y cálmate )

 
A la espera de las mediciones)
 
Alexey Navoykov:

No podría hacer otra cosa porque tú mismo has interferido en la optimización con puntos de ruptura. El punto de la optimización es que no debe cambiar la lógica del algoritmo. Por eso no se puede detectar explícitamente. Si hay un punto de interrupción ahí, el compilador naturalmente no tiene derecho a cortar este código. ¿Esperabas que el compilador pudiera saltar el punto de interrupción? )

Sólo se puede detectar la optimización compilando el código o midiendo su rendimiento, así que eso es lo primero que hay que hacer. Y cálmate )

Hombre, eso es una tontería salvaje, qué hay que comentar, un completo malentendido de cómo funciona el depurador.

Acerca de la velocidad - gestor de memoria no es tan tonto, y no el hecho de que va a pedir al sistema operativo, puede sobreutilizar anterior asignado. En general, úsalo como quieras, depende de ti. Pero no debe convencer a los demás de ello, al menos hasta que aporte pruebas concretas, ¿dónde están?