Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 808

 
Kos Mos:

Portanto, estou tentando descobrir no que estou falhando, entendo que é provável que ninguém me diga nada de graça - capitalismo, pelo amor de Deus)). Não tenho nada contra isso, só preciso entender por que os negócios se abrem em cada vela na direção da compra.

Não estava respondendo a você.

Se você quiser que seus esquis funcionem, você tem pelo menos que imprimir os valores das variáveis que são importantes quando o sinal é recebido e olhar no log para ver o que acontece com eles.

 

Existe um loop para(int i=0;i<ArrayRange(arr2,0);i++), então eu quero saber quantas vezes este cálculo ArrayRange(arr2,0) é realizado: uma vez e a máquina se lembra do valor, ou toda vez que o loop está funcionando, o valor é retornado da função ArrayRange(arr2,0)? Exemplo:

1ª opção.

i=0,i<(valor retornado), incremento, então

i<(valor de retorno novamente), incremento, então

i<(mais uma vez retorna um valor), incrementar desta forma,

2ª variante.

ou, retornamos um valor deste cálculo ArrayRange(arr2,0) uma vez, deixamos que ele retorne 5 e a máquina se lembre deste 5 e obtenhamos o seguinte resultado

i=0,i<(valor retornado)i<5, incremento, então

i<5, incremento, então

i<5, incremento - é assim que funciona?

Estou perguntando por quê: se tudo acontece pela primeira variante, então faz sentido extrair este valor antes do loop e armazená-lo em uma variável, para que o programa não calcule a função ArrayRange(arr2,0) em cada passagem do loop.

 
Seric29:

Existe um loop para(int i=0;i<ArrayRange(arr2,0);i++), então eu quero saber quantas vezes este cálculo ArrayRange(arr2,0) é realizado: uma vez e a máquina se lembra do valor, ou toda vez que o loop está funcionando, o valor é retornado da função ArrayRange(arr2,0)? Exemplo:

1ª opção.

i=0,i<(valor retornado), incremento, então

i<(valor de retorno novamente), incremento, então

i<(mais uma vez retorna um valor), incrementar desta forma,

2ª variante.

ou, retornamos um valor deste cálculo ArrayRange(arr2,0) uma vez, deixamos que ele retorne 5 e a máquina se lembre deste 5 e obtenhamos o seguinte resultado

i=0,i<(valor retornado)i<5, incremento, então

i<5, incremento, então

i<5, incremento - é assim que funciona?

Por que estou perguntando: se tudo acontece na primeira variante, então faz sentido antes do loop extrair primeiro este valor e armazená-lo em uma variável, para que em cada passagem do loop o programa não faça a função ArrayRange(arr2,0).

no caso geral - 1º caso.

PS/ 2nd só é possível para compiladores "otimizadores", que podem entender que se não há ArrayResize dentro de um loop, então ArrayRange:=const ; não tenho certeza de que o compilador mql já cava tão fundo no código, embora para suas funções "nativas" isto seja teoricamente possível.

PPS/ o exemplo com ArrayRange() não é muito correto, porque provavelmente não haverá uma chamada de função direta, o compilador só tem que reduzi-lo a comparar i com uma variável de array interna, porque ele sabe tudo sobre arrays.

 
Maxim Kuznetsov:

no caso geral - 1ª variante.

PS/ 2nd só é possível para compiladores "otimizadores", que podem entender que se não há ArrayResize dentro do loop, então ArrayRange:=const ; não tenho certeza se o compilador mql já escava tão fundo no código, embora para suas funções "nativas" isso seja teoricamente possível.

PPS/ exemplo com ArrayRange() não é muito correto, porque provavelmente não haverá uma chamada de função direta, o compilador só tem que reduzi-lo à comparação de i com a variável array interna, porque ele sabe tudo sobre arrays.

Vamos pegar a expressão5+5*5

a 1ª variante.

i=0,i<(5+5*5), incremento, então

i<(5+5*5), incremento, então

i<(5+5*5), incrementar desta forma,

2ª variante.

ou, neste caso, o resultado é um único retorno de 5+5*5, deixe-os retornar 30 e a máquina se lembra deste 30-ku, então obtemos os seguintes resultados

i=0,i<(valor retornado) i<30, incremento, em seguida (o motor se lembra automaticamente de 30 porque eu não economizei 30 em algum lugar)

i<30, incremento, então

i<30, incremento, é assim que funciona?

Presumo que será a 1ª variante? 5+5*5 é uma expressão que será avaliada em cada iteração do laço. Você pode calcular esta expressão antes do loop e armazenar 30 em uma variável e alimentá-la no loop, o que será mais fácil para a máquina, a menos que ela calcule automaticamente estes 30 e os armazene em sua memória.


Se não houver chamada de função, o compilador não pode verificar a expressão booleana i<5, então provavelmente a primeira opção funcionará.

 

O resultado de uma função(ArrayRange) pode ser alterado dentro de um loop ou função.
E a expressão constante(5+5*5) será sempre a mesma.

Portanto, a função será calculada em cada passe.
E o valor constante será substituído no código pelo compilador no momento da compilação.

 
Taras Slobodyanik:

O resultado de uma função(ArrayRange) pode ser alterado dentro de um loop ou função.
E a expressão constante(5+5*5) será sempre a mesma.

Portanto, a função será calculada em cada passe.
E o valor constante será substituído no código pelo compilador no momento da compilação.

5+5*5 também é uma expressão e precisa ser calculada a cada passagem, pois para a função é suposto retornar o mesmo resultado, o ponto é que a cada passagem do loop o compilador ainda irá calcular tanto a função quanto a expressão 5+5*5. Portanto, será a primeira opção - ou seja, o cálculo é realizado a cada passagem do loop, então faz sentido contar este valor antes do loop e armazená-lo em uma variável e usar a variável como o mesmo valor estático para que nenhum cálculo ocorra a cada passagem do loop, isto em última instância pode

int k=5+5*5;//k=30

for(int i=0;i<k;i++){}

onde k é sempre 30 ou

int k=ArrayRange(arr2,0)//k=5

for(int i=0;i<k;i++){}

onde k é sempre igual a 5.

 
Seric29:

5+5*5 também é uma expressão e deve ser calculada em cada passagem, pois para a função é suposto retornar o mesmo resultado, a questão é que em cada passagem do loop o compilador ainda contará tanto a função quanto a expressão 5+5*5. Portanto, será a primeira opção - ou seja, o cálculo é realizado em cada passagem do loop, portanto faz sentido contar este valor antes do loop e armazená-lo em uma variável e usar a variável como o mesmo valor estático para que nenhum cálculo ocorra em cada passagem do loop, eventualmente ele poderá

int k=5+5*5;//k=30

for(int i=0;i<k;i++){}

onde k é sempre 30 ou

int k=ArrayRange(arr2,0)//k=5

for(int i=0;i<k;i++){}

onde k é sempre igual a 5.

Você poderia simplesmente expandir o loop e não criar variáveis extras.

 
Seric29:

5+5*5 também é uma expressão e precisa ser calculada a cada passagem, já que para a função é suposto retornar o mesmo resultado, estamos falando do fato de que a cada passagem do ciclo o compilador ainda contará tanto a função quanto a expressão 5+5*5. Portanto, haverá a primeira opção - ou seja, o cálculo é feito a cada passagem do ciclo, então faz sentido contar este valor antes do ciclo e armazenar em uma variável e usar a variável como o mesmo valor estático para que não haja cálculos a cada passagem do ciclo, eventualmente mo

O compilador sempre funciona uma vez - no momento da compilação do texto no código.
(tanto quanto me lembro, o MT4 também já compila diretamente ao código)

5+5*5 - esta é uma expressão com constantes, elas não precisam ser recalculadas - por isso será calculada apenas uma vez, em tempo de compilação, e o código conterá o número 30

5+5*5+i é uma expressão com uma variável, e esta será calculada no código em cada passe como 30+i

A funçãoArrayRange retorna um valor, mas o compilador não sabe qual será esse valor, então ele substituirá a chamada de função no código, e a cada passagem (no código) a função será chamada
 
Taras Slobodyanik:

O compilador sempre funciona uma vez - no momento da compilação do texto em código.
(tanto quanto me lembro, o MT4 já compila diretamente ao código)

5+5*5 é uma expressão com constantes, não precisam ser recalculadas - portanto, isto só será calculado uma vez, em tempo de compilação, e no código será 30

5+5*5+i é uma expressão com uma variável, e será calculada no código em cada passe como 30+i

A funçãoArrayRange retorna um valor, mas o compilador não sabe qual será esse valor, então ele substituirá a chamada de função no código, e a cada passagem (no código) a função será chamada

Estou vendo. Obrigado. Não é uma questão séria, é claro, mas há sutilezas.

 
Artyom Trishkin:

Você pode simplesmente expandir o loop e não criar variáveis extras.

no meu caso, há 2 expressões matemáticas 1st-ArrayRange(arr2,0) 2nd5+5*5 meu objetivo é criar condições sob as quais o compilador trabalhará com menos carga

for(int i=0;i<ArrayRange(arr2,0);i++) neste caso o valor de comparação é retornado a cada passagem

int k=ArrayRange(arr2,0)//k=5 for(int i=0;i<k;i++){} neste caso o valor de comparação é retornado 1 vez ao invés de 4 vezes, mas uma variável é criada, no entanto a carga é menor, especialmente quando estamos falando de milhares ou milhões.

Você pode nos mostrar como expandir um loop para que não tenhamos que criar variáveis?

Razão: