Características del lenguaje mql5, sutilezas y técnicas - página 49

 
fxsaber:

Si se pulsa TAB inmediatamente después de las palabras if, else, while, for, do, hay una pequeña construcción extra...


joder... genial, después de 5 años conociendo a mql - me he enterado.

 

Conclusiones de una conversación en la SD sobre un problema planteado.

Resulta que asignar un valor a una variable de cadena es una operación MUY costosa.

Tan caro que es conveniente evitarlo si es posible, hasta que los desarrolladores mejoren este punto en el compilador, lo que no parece que vaya a ocurrir pronto.


Como ejemplo, si se ejecuta una carrera de ticks reales durante un mes en FIBO, sería alrededor de 1 millón de ticks. Si obtienes el valor de PositionGetString en cada tick y lo comparas con algo, el rendimiento sería aceptable, pero si primero asignas el resultado de la función a una variable de cadena antes de compararlo, entonces la duración de la ejecución aumentaría aproximadamente un segundo.


Si parece poca cosa, es una visión equivocada. Cuando un EA de este tipo se ejecuta en modo de optimización durante varios miles de pases, ese segundo extra se traduce en horas adicionales de tiempo de espera. Es decir, una asignación de cadena inofensiva puede causar horas adicionales de espera durante la optimización. Tenga cuidado y tenga en cuenta este matiz.


En kodobase, existe una pequeña herramienta que permite detectar estos fallos en diferentes implementaciones de la misma lógica comercial. Escribir código rápido.

 
fxsaber:

Conclusiones de una conversación en la SD sobre un problema planteado.

Resulta que asignar un valor a una variable de cadena es una operación MUY costosa.

Tan caro que es conveniente evitarlo si es posible, hasta que los desarrolladores mejoren este punto en el compilador, lo que no parece que vaya a ocurrir pronto.


Como ejemplo, si se ejecuta una carrera de ticks reales durante un mes en FIBO, sería alrededor de 1 millón de ticks. Si se obtiene el valor de PositionGetString en cada tic y se compara con algo, el rendimiento sería aceptable, pero si se asigna primero el resultado de la función a una variable de cadena y luego se compara antes de la comparación, la duración de la ejecución aumentaría aproximadamente un segundo.


Si parece poca cosa, es una visión equivocada. Cuando un EA de este tipo se ejecuta en modo de optimización durante varios miles de pases, ese segundo extra se traduce en horas adicionales de tiempo de espera. Es decir, una asignación de cadena inofensiva puede causar horas adicionales de espera durante la optimización. Tenga cuidado y tenga en cuenta este matiz.


En kodobase, existe una pequeña herramienta que permite detectar estos fallos en diferentes implementaciones de la misma lógica comercial. Escribe un código rápido.

Gracias, no pensé que fuera posible. Lo tendré en cuenta en futuros desarrollos

 

Una simple adivinanza para dormir, ¿por qué los resultados amarillos?

struct INT
{
  int Array[];
  
  INT()
  {
    Print(__FUNCTION__); // до сюда не дойдет
  }
};

void OnStart()
{
  INT i = {0};
  
  Print(ArrayResize(i.Array, 5)); // -1
}
 
fxsaber:

Una simple adivinanza para dormir, ¿por qué los resultados amarillos?

Debido a que la estructura está empaquetada con ceros, no por el constructor, por lo que la estructura del array se inicializa incorrectamente, a arrayresize no le gustan tales arrays, mi código se estrelló en tal redimensionamiento.
 
Combinador:
Debido a que la estructura está llena de ceros, no el constructor, por lo que la estructura de la matriz se inicializa incorrectamente, arrayresize no le gusta tales matrices, mi código se estrelló en tal redimensionamiento en absoluto.

Es bueno que todo el mundo lo sepa.

 
Slava:

Se refiere a GetMicrosecondCount. No hay una forma definitiva de saber si está ralentizando el servidor. Puede tener un efecto indirecto. Por lo tanto, es mejor utilizar el GetTickCount nativo del sistema

GetMicrosecondCount se utiliza para medir periodos cortos de ejecución de código. Para medir un gran número de ejecuciones OnTick, es mejor utilizar GetTickCount.

Intente utilizar GetMicrosecondsCount en lugar de GetTickCount cuando obtenga resultados estables. Me lo contarás aquí. Quizás me estoy preocupando demasiado.

Tu hipótesis resultó ser correcta, una llamada múltiple de GetMicrosecondsCount provoca unos retrasos terribles en el probador. Sin embargo, GetTickCount tiene el mismo efecto.
 
fxsaber:

Conclusiones de una conversación en la SD sobre un problema planteado.

Resulta que asignar un valor a una variable de cadena es una operación MUY costosa.

Tan caro que es conveniente evitarlo si es posible, hasta que los desarrolladores mejoren este punto en el compilador, lo que no parece que vaya a ocurrir pronto.


Como ejemplo, si se ejecuta una carrera de ticks reales durante un mes en FIBO, sería alrededor de 1 millón de ticks. Si obtienes el valor de PositionGetString en cada tick y lo comparas con algo, el rendimiento sería aceptable, pero si primero asignas el resultado de la función a una variable de cadena antes de compararlo, entonces la duración de la ejecución aumentaría aproximadamente un segundo.


Si parece poca cosa, es una visión equivocada. Cuando un EA de este tipo se ejecuta en modo de optimización durante varios miles de pases, ese segundo extra se traduce en horas adicionales de tiempo de espera. Es decir, una asignación de cadena inofensiva puede causar horas adicionales de espera durante la optimización. Tenga cuidado y tenga en cuenta este matiz.


En kodobase, existe una pequeña herramienta que permite detectar estos fallos en diferentes implementaciones de la misma lógica comercial. Escribe un código rápido.

struct STRUCT
{
  string Str;
  
  string Get() const { return(this.Str); }
};

void OnStart()
{
  STRUCT Struct;
  
  Print(Struct.Str);
  Print(Struct.Get()); // Выполняется гораздо дольше, чем предыдущая строка
}
 
fxsaber:

Resulta que asignar un valor a una variable de cadena es una operación MUY cara.

...

Si primero se asigna el resultado de una función a una variable de cadena antes de compararla, y luego se compara, el tiempo de ejecución aumentará aproximadamente un segundo.

Tal y como yo lo veo, el problema no es tanto la asignación cara, sino que el compilador no elimina esta asignación innecesaria del código por alguna razón, aunque debería hacerlo. Es decir, el código compilado debe ser el mismo en ambos casos.
 
Alexey Navoykov:
Según tengo entendido, el problema no está tanto en la asignación cara, sino en que el compilador no elimina esta asignación innecesaria del código por alguna razón, aunque debería hacerlo. Es decir, el código compilado debe ser el mismo en ambos casos.

Este es un problema menor. Sí, el optimizador del compilador todavía no sabe cómo optimizar esos momentos de cadena. Pero es en la asignación de cadenas donde radica el problema de la ralentización.

Escribir código que no pueda ser optimizado por el compilador y al mismo tiempo hacer asignaciones en él. Y verás lo que es una desaceleración.

El ejemplo de la lectura de un campo de cadena de una estructura a través de una función es exactamente la forma en que se implementa la lectura de las propiedades de posición en MT4/5.

En MT4, el mismo OrderSymbol() se frena si se implementa en MT5. Los propios desarrolladores intentan pasar a sus funciones cadenas a través de enlaces.

Por lo tanto, si se escribe algo así

if ((OrderSymbol() == Symb) && (OrderMagicNumber == Magic))

siempre es mejor poner la condición OrderSymbol() al final de la condición general.


He notado una aparente ralentización en superficies aparentemente lisas cuando uso TesterBench.