Características da linguagem mql5, subtilezas e técnicas - página 238

 

Nunca imaginei que usaria um trecho de código gerado por máquina no código-fonte. Especialmente em um local que é um arquivo para desempenho.


Abaixo está o código gerado.

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));
}

Um script muito mais conciso foi escrito para a geração. Ele pode ser conveniente para testar hipóteses rapidamente e evitar erros humanos.

 
fxsaber #:

Nunca imaginei que usaria um trecho de código gerado por máquina no código-fonte. Especialmente em um local de importância arquivística para o desempenho.


Abaixo está o código gerado.

Um script muito mais conciso foi escrito para a geração. Isso pode ser útil para testar hipóteses rapidamente e evitar erros humanos.

Tenha cuidado, o mesmo ChatGPT comete muitos erros, tanto na sintaxe quanto na lógica, portanto, você precisa verificar tudo duas vezes.

Mas ele é realmente um bom gerador, pois ajuda você a expressar ideias em código.

 
fxsaber #:

Abaixo está o código gerado.

Um script muito mais conciso foi escrito para a geração. Isso pode ser útil para testar hipóteses rapidamente e evitar erros humanos.

Não há informações básicas suficientes: o novo código ficou mais rápido do que o código antigo ou não?

Se não, por que trocar o código antigo compreensível pelo novo incompreensível?

Em caso afirmativo, por que o compilador MQL não conseguiu gerar o código ideal em termos de desempenho de uma só vez, já que ele tem muito mais possibilidades para isso do que o chat

 
Aleksey Vyazmikin #:

Tenha cuidado, pois o mesmo ChatGPT comete muitos erros, tanto de sintaxe quanto de lógica, portanto, você precisa verificar tudo duas vezes.

Mas ele é realmente um bom lançador, pois ajuda a expressar ideias em código.

Geração de 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 #:

Não há informações básicas suficientes: o novo código ficou mais rápido do que o antigo ou não?

O novo código é mais rápido.

Se sim, então por que o compilador MQL não conseguiu gerar o código ideal em termos de desempenho de uma só vez, enquanto ele tem muito mais possibilidades para isso do que o chat?

Isso é otimização algorítmica, não otimização do compilador.

 
fxsaber #:

O novo é mais rápido.

Isso é otimização algorítmica, não otimização do compilador.

Quanto mais rápido? Em 1,5% ou 1,5 vezes? E como se fosse mais rápido? Ou com base em medições corretas?

Então você não deu a ele um código, mas um algoritmo?

 
A100 #:

Quanto mais rápido? Em 1,5 por cento ou 1,5 vezes? E pelo tato ou por medições específicas?

Então você não deu a ele um código, mas um algoritmo?

É isso que o código-fonte do Virtual usa. Você precisa fazer quatro verificações em cada tique.

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


Mas, em algumas situações (chave 0-15), você pode fazer menos verificações: 0-4. Isso depende do TS.


Por exemplo, se o TS abrir/fechar posições somente com ordens a mercado e não usar SL/TP, não será necessário fazer uma única verificação.

Mas se todos os tipos de ordens forem usados simultaneamente, você precisará fazer todas as quatro verificações: não haverá aceleração.


É por isso que você deve pegar um TS específico e observar os resultados das medições para ele. Diferentes TS têm diferentes resultados de aceleração.


Era possível classificar os casos (número de casos) em mais variantes. Para ser franco, não consegui fazer isso.

 

Na MQL5, há uma função StringReserve, com a qual podemos, teoricamente, reduzir o número de realocações de memória para nossa string: alocamos um buffer grande o suficiente de uma vez e depois trabalhamos nele.

Mas, como mostra a prática, qualquer atribuição subsequente de um valor a essa cadeia de caracteres altera o tamanho de seu buffer (ou seja, aparentemente, ocorre uma realocação de memória).

Como resultado, em vez de

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

faz sentido usar

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

faz sentido usar

Exatamente. Esse mecanismo funciona muito bem no preenchimento de strings. Por exemplo, ao gerar grandes relatórios HTML.

 

Como posso saber se um símbolo tem dados, para não deixá-lo na janela [Market Watch] se não tiver?

Eu uso essa verificação em um loop:

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

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

Mas, depois disso, não consigo remover manualmente os símbolos da janela [Market Watch], nem um por um nem todos de uma vez, enquanto o Expert Advisor está no gráfico: