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

 

Nunca imaginé que utilizaría un fragmento de código generado por una máquina en el código fuente. Especialmente en un lugar que es de archivo para el rendimiento.


A continuación se muestra el código generado.

switch (this.Flag)
{
case 0:
  return(false);
case 1:
  return(Tick.bid >= this.bid.Max);
case 2:
  return(Tick.ask <= this.ask.Min);
case 3:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min));
case 4:
  return(Tick.bid <= this.bid.Min);
case 5:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min));
case 6:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 7:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min));
case 8:
  return(Tick.ask >= this.ask.Max);
case 9:
  return((Tick.bid >= this.bid.Max) || (Tick.ask >= this.ask.Max));
case 10:
  return((Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 11:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.ask >= this.ask.Max));
case 12:
  return((Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 13:
  return((Tick.bid >= this.bid.Max) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 14:
  return((Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
case 15:
  return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));
}

Se escribió un script mucho más conciso para la generación. Puede ser conveniente para probar rápidamente hipótesis y evitar errores humanos.

 
fxsaber #:

Nunca imaginé que utilizaría un fragmento de código generado por una máquina en el código fuente. Sobre todo en un lugar de importancia archivística para el rendimiento.


A continuación se muestra el código generado.

Se escribió un script mucho más conciso para la generación. Esto puede ser útil para probar rápidamente hipótesis y evitar errores humanos.

Ten cuidado, el mismo ChatGPT comete muchos errores, tanto en sintaxis como en lógica, así que tienes que comprobarlo todo dos veces.

Pero es realmente un buen generador, te ayuda a expresar ideas en código.

 
fxsaber #:

A continuación se muestra el código generado.

Se ha escrito un script mucho más conciso para la generación. Esto puede ser útil para probar rápidamente hipótesis y evitar errores humanos.

No hay suficiente información de fondo: ¿era el nuevo código más rápido que el antiguo o no?

En caso negativo, ¿por qué cambiar el antiguo código comprensible por el nuevo incomprensible?

En caso afirmativo, ¿por qué el compilador MQL no pudo generar el código óptimo en términos de rendimiento de una vez, mientras que tiene muchas más posibilidades para ello que el chat

 
Aleksey Vyazmikin #:

Ten cuidado, el mismo ChatGPT comete muchos errores, tanto de sintaxis como de lógica, así que tienes que comprobarlo todo dos veces.

Pero es un lanzador realmente bueno, ayuda a expresar ideas en código.

Generar script.

// Генерация switch-кода.
string GetString( const int Num )
{
  static const string Condition[] = {"(Tick.bid >= this.bid.Max)", "(Tick.ask <= this.ask.Min)",
                                     "(Tick.bid <= this.bid.Min)", "(Tick.ask >= this.ask.Max)"};
  string Str = NULL;

  for (int i = 0; i < ArraySize(Condition); i++)
    if ((bool)(Num & (1 << i)))
      Str += ((Str == NULL) ? NULL : " || ") + Condition[i];

  return(Str);
}

void OnStart()
{
  for (int i = 0; i < 16; i++)
    Print("case " + (string)i + ":\n  return(" + GetString(i) + ");");
}
 
A100 #:

No hay suficiente información de fondo: ¿el nuevo código es más rápido que el antiguo o no?

El nuevo código es más rápido.

Si es así, entonces ¿por qué el compilador MQL no pudo generar el código óptimo en términos de rendimiento a la vez, mientras que tiene muchas más posibilidades para esto que el chat

Esto es optimización algorítmica, no optimización del compilador.

 
fxsaber #:

El nuevo es más rápido.

Se trata de una optimización algorítmica, no del compilador.

¿Cuánto más rápido? ¿En un 1,5% o 1,5 veces? ¿Y como si fuera más rápido? ¿O basado en mediciones correctas?

¿Así que no le diste un código, sino un algoritmo?

 
A100 #:

¿Cuánto más rápido? ¿En un 1,5 por ciento o en 1,5 veces? ¿Y por tacto o por mediciones concretas?

¿Así que no le diste un código, sino un algoritmo?

Eso es lo que utiliza el código fuente de Virtual. Tiene que hacer cuatro comprobaciones en cada tick.

return((Tick.bid >= this.bid.Max) || (Tick.ask <= this.ask.Min) || (Tick.bid <= this.bid.Min) || (Tick.ask >= this.ask.Max));


Pero en algunas situaciones (interruptor 0-15) se puede hacer con menos comprobaciones: 0-4. Depende de la ST.


Por ejemplo, si el ST abre/cierra posiciones sólo con órdenes de mercado y no utiliza SL/TP, entonces no necesita hacer ni una sola comprobación.

Pero si se utilizan todos los tipos de órdenes simultáneamente, necesita hacer las cuatro comprobaciones: no habrá aceleración.


Por eso debe tomar una TS específica y mirar los resultados de las mediciones para ella. Diferentes TS tienen diferentes resultados de aceleración.


Era posible clasificar los casos (número de casos) en más variantes. Yo no podría hacerlo, francamente hablando.

 

En MQL5, existe una función StringReserve, con la que teóricamente podemos reducir el número de reasignaciones de memoria para nuestra cadena: asignamos un búfer suficientemente grande de una vez y luego trabajamos en él.

Pero, como demuestra la práctica, cualquier asignación posterior de un valor a esta cadena cambia el tamaño de su búfer (es decir, aparentemente se produce una reasignación de memoria).

En consecuencia, en lugar de

string str;
str.Reserve(8192);
str="test";

tiene sentido utilizar

string str;
str.Reserve(8192);
StringSetLength(str,0);  // или str.SetLen(0); - в документации есть, но у меня в 4073 не поддерживается
str+="test";
 
JRandomTrader #:

tiene sentido utilizar

Exacto. Este mecanismo funciona muy bien en la finalización de cadenas. Por ejemplo, al generar informes HTML de gran tamaño.

 

¿Cómo puedo averiguar si un símbolo tiene datos, para no dejarlo en la ventana [Observación del mercado] si no los tiene?

Utilizo tal comprobación en un bucle:

ulong first_server_date = (ulong)SeriesInfoInteger(symbol, PERIOD_M1, SERIES_SERVER_FIRSTDATE);

if(first_server_date == NULL) {
  SymbolSelect(symbol, false);
  continue;
}

Pero después no puedo quitar manualmente los símbolos de la ventana [Observación del Mercado], ya sea uno por uno o todos a la vez, mientras que el Asesor Experto está en el gráfico:


Razón de la queja: