Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 808

 
Kos Mos:

так я и пытаюсь выяснить что именно у меня не получается, я понимаю что бесплатно вряд ли кто то что то подскажет - капитализм мать его.)) Ничего против не имею, мне просто нужно понять почему на каждой свече в бай направлении открываются сделки.

Я не вам отвечал.

Вам - чтобы лыжи поехали - нужно хотя бы распечатать значения переменных, важных при получении сигнала, да поглядеть в журнале что там выходит с ними.

 

Есть такой цикл for(int i=0;i<ArrayRange(arr2,0);i++), значит мне интересно вот это вычисление ArrayRange(arr2,0) сколько раз производится: один раз и машина запоминает значения, или каждый раз когда крутиться цикл происходит возврат значения из функции ArrayRange(arr2,0)? Пример:

1ый вариант.

       i=0,i<(возвращаемого значения), инкремент, далее 

             i<(опять возвращаем значение), инкремент, далее 

             i<(опять возвращаем значение), инкремент так оно получается, 

2ой вариант.

или происходит один раз возврат значения из этого вычисления ArrayRange(arr2,0), допусти вернули 5 и машина запоминает эту 5ку и получается такой расклад

       i=0,i<(возвращаемого значения)т.е i<5, инкремент, дальше 

             i<5, инкремент, далее 

             i<5, инкремент так оно получается?

Я почему спрашиваю: если всё происходит по первому варианту, то имеет смысл перед циклом это значение предварительно извлечь и сохранить в переменную чтобы на каждом проходе цикла программа не производила вычисление функции ArrayRange(arr2,0).

 
Seric29:

Есть такой цикл for(int i=0;i<ArrayRange(arr2,0);i++), значит мне интересно вот это вычисление ArrayRange(arr2,0) сколько раз производится: один раз и машина запоминает значения, или каждый раз когда крутиться цикл происходит возврат значения из функции ArrayRange(arr2,0)? Пример:

1ый вариант.

       i=0,i<(возвращаемого значения), инкремент, далее 

             i<(опять возвращаем значение), инкремент, далее 

             i<(опять возвращаем значение), инкремент так оно получается, 

2ой вариант.

или происходит один раз возврат значения из этого вычисления ArrayRange(arr2,0), допусти вернули 5 и машина запоминает эту 5ку и получается такой расклад

       i=0,i<(возвращаемого значения)т.е i<5, инкремент, дальше 

             i<5, инкремент, далее 

             i<5, инкремент так оно получается?

Я почему спрашиваю: если всё происходит по первому варианту, то имеет смысл перед циклом это значение предварительно извлечь и сохранить в переменную чтобы на каждом проходе цикла программа не производила вычисление функции ArrayRange(arr2,0).

в общем случае - 1-й вариант.

PS/ 2-й возможен только для "оптимизирующих" компиляторов, которые могут сообразить что если внутри цикла нет ArrayResize, то ArrayRange:=const ; не уверен что компилятор mql уже настолько глубоко копает код, хотя для его "родных" функций это теоретически возможно.

PPS/ пример с ArrayRange() не вполне корректен, потому-что непосредственного вызова функции наверняка не будет, компилятор просто обязан сократить это до сравнения i с внутренней переменной массива, потому-что про массивы он знает всё .

 
Maxim Kuznetsov:

в общем случае - 1-й вариант.

PS/ 2-й возможен только для "оптимизирующих" компиляторов, которые могут сообразить что если внутри цикла нет ArrayResize, то ArrayRange:=const ; не уверен что компилятор mql уже настолько глубоко копает код, хотя для его "родных" функций это теоретически возможно.

PPS/ пример с ArrayRange() не вполне корректен, потому-что непосредственного вызова функции наверняка не будет, компилятор просто обязан сократить это до сравнения i с внутренней переменной массива, потому-что про массивы он знает всё .

ну давайте возьмём такой вариант есть выражение 5+5*5 как будет

1ый вариант.

       i=0,i<(5+5*5), инкремент, далее 

             i<(5+5*5), инкремент, далее 

             i<(5+5*5), инкремент так оно получается, 

2ой вариант.

или происходит один раз возврат значения из этого вычисления 5+5*5, допусти вернули 30и машина запоминает эту 30ку и получается такой расклад

       i=0,i<(возвращаемого значения)т.е i<30, инкремент, дальше (машина автоматически запоминает 30т.к. я не куда 30 не сохранял)

                                                              i<30, инкремент, далее 

                                                              i<30, инкремент так оно получается?

Я так понял будет 1ый вариант? 5+5*5 это выражение на каждом проходе цикла программа будет это выражение вычислять. Можно это выражение вычислить перед циклом и сохранить 30 в переменную и подставить её в цикл машине будет легче если конечно она автоматически не вычислит эту 30ку и не запомнит сама.


Если не будет вызова функции то компилятор не сможет проверить логическое выражение i<5 значит наверное первый вариант будет выполнятся.

 

Результат функции (ArrayRange) может быть изменен внутри цикла или функцией.
А постоянное выражение (5+5*5) всегда будет одним и тем же.

Поэтому функция будет рассчитываться на каждом проходе.
А постоянное значение будет подставлено компилятором в код при компиляции.

 
Taras Slobodyanik:

Результат функции (ArrayRange) может быть изменен внутри цикла или функцией.
А постоянное выражение (5+5*5) всегда будет одним и тем же.

Поэтому функция будет рассчитываться на каждом проходе.
А постоянное значение будет подставлено компилятором в код при компиляции.

5+5*5 это тоже выражение и его нужно рассчитать на каждом проходе, что касается функции то предполагается возврат одинакового результата, речь идёт о том что на каждом проходе цикла компилятор всё равно будет считать как и функцию так и выражение 5+5*5. Значит будет первый вариант - т.е. расчёт производится на каждом проходе цикла, поэтому имеет смысл посчитать это значение перед циклом и сохранить в переменную и использовать переменную как одинаковое статическое значение чтобы не происходило никаких расчётов на каждом проходе цикла, это в конечном итоге может сказать на производительности программы.

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

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

где k всегда равно 30 или

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

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

где k всегда равно 5.

 
Seric29:

5+5*5 это тоже выражение и его нужно рассчитать на каждом проходе, что касается функции то предполагается возврат одинакового результата, речь идёт о том что на каждом проходе цикла компилятор всё равно будет считать как и функцию так и выражение 5+5*5. Значит будет первый вариант - т.е. расчёт производится на каждом проходе цикла, поэтому имеет смысл посчитать это значение перед циклом и сохранить в переменную и использовать переменную как одинаковое статическое значение чтобы не происходило никаких расчётов на каждом проходе цикла, это в конечном итоге может сказать на производительности программы.

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

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

где k всегда равно 30 или

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

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

где k всегда равно 5.

Можно просто развернуть цикл, и не создавать лишние переменные.

 
Seric29:

5+5*5 это тоже выражение и его нужно рассчитать на каждом проходе, что касается функции то предполагается возврат одинакового результата, речь идёт о том что на каждом проходе цикла компилятор всё равно будет считать как и функцию так и выражение 5+5*5. Значит будет первый вариант - т.е. расчёт производится на каждом проходе цикла, поэтому имеет смысл посчитать это значение перед циклом и сохранить в переменную и использовать переменную как одинаковое статическое значение чтобы не происходило никаких расчётов на каждом проходе цикла, это в конечном итоге может сказать на производительности программы.

Компилятор работает всегда один раз - в момент компиляции текста в код.
(насколько помню МТ4 уже тоже компилирует сразу в код)

5+5*5 - это выражение с постоянными, их не нужно пересчитывать - поэтому это будет рассчитано только один раз, при компиляции, и в коде будет цифра 30

5+5*5+i - это выражение с переменной, и это будет рассчитываться в коде на каждом проходе как 30+i

функция ArrayRange возвращает значение, каким будет это значение компилятор не знает, поэтому в код подставит вызов функции, и на каждом проходе (в коде) будет вызываться функция
 
Taras Slobodyanik:

Компилятор работает всегда один раз - в момент компиляции текста в код.
(насколько помню МТ4 уже тоже компилирует сразу в код)

5+5*5 - это выражение с постоянными, их не нужно пересчитывать - поэтому это будет рассчитано только один раз, при компиляции, и в коде будет цифра 30

5+5*5+i - это выражение с переменной, и это будет рассчитываться в коде на каждом проходе как 30+i

функция ArrayRange возвращает значение, каким будет это значение компилятор не знает, поэтому в код подставит вызов функции, и на каждом проходе (в коде) будет вызываться функция

Понятно. Спасибо. Вопрос конечно не серьёзный но нюансы есть нюансы.

 
Artyom Trishkin:

Можно просто развернуть цикл, и не создавать лишние переменные.

в моём случае есть 2 математических выражения 1ое-ArrayRange(arr2,0) 2-ое 5+5*5 моя цель создать условия при которых компилятор будет работать с меньшей нагрузкой

 for(int i=0;i<ArrayRange(arr2,0);i++) в этом случае возврат значения сравнения происходит на каждом проходе

int k=ArrayRange(arr2,0)//k=5  for(int i=0;i<k;i++){}в этом случае возврат значения сравнения происходит 1 раз а не 4 раза но создаётся переменная, тем не менее нагрузка здесь меньше особенно если речь идёт о тысячах или миллионах.

Покажите как развернуть цикл чтобы не создавать переменные?