Ошибки, баги, вопросы - страница 1999

 
Alexey Viktorov:

Давайте возьмём к примеру массив буфер индикатора: При инициализации индикатора буфер имеет нулевую длину. Что там инициализировать нулями? При добавлении очередного индекса его принудительно обнулять и потом заполнять каким-то значением??? Для чего это обнуление или заполнение EMPTY_VALUE? А если есть необходимость назначить PLOT_EMPTY_VALUE и не 0 и не EMPTY_VALUE или принудительно одно, а надо другое... Как ни крути получается лишняя трата времени...

А пользовательский массив... Массив-то объявляется для каких-то данных отличных от нуля и EMPTY_VALUE. Так с какой целью его принудительно инициализировать чем-то?

Вот и получается, что на быстродействие в большинстве случаев сказывается.

Я видимо отстал от жизни. По мне так индикаторный буфер всегда имеет длину равную количеству баров. И отказ от его инициализации в МТ5 приводит к тому, что на экран выводится мусор. Получается, что явная инициализация обязательна. И зачем она просто напросто переложена с ядра (как было в МТ4) на программиста MQL - не понятно. Реальных доводов о том, что как-то можно ускориться не делая инициализации и при этом не получить отображения мусора, я не видел.

Про пользовательский динамический массив я ничего не говорю - там действительно действует правило: тот кто его аллоцировал, тот и ответственен за правильную чистку. ArrayInitialize во многих случаях полезен. Это не вопрос быстродействия, а корректности работы программы. Расставьте приоритеты: быстро и/или правильно. Обычно некоторые проверки на правильность и подготовка данных требуют дополнительных расходов по времени (хоть и минимальных), но без этого никуда - чудес не бывает.

 
Stanislav Korotky:

Про пользовательский динамический массив я ничего не говорю - там действительно действует правило: тот кто его аллоцировал, тот и ответственен за правильную чистку.

Не надо массивы обижать.

#property strict

void OnStart()
{
  uchar Array[];
  
  const int Size = ArrayResize(Array, 10000);
  
  bool Res = false;
  
  for (int i = 0; (i < Size) && (!Res); i++)
    Res = Array[i];
    
  Print(Res);
}

 В MT4 будет всегда возврат false, потому как без мусора - все нулями. В MT5 - true.

Поэтому один и тот же код в MT4-тестере будет всегда показывать идентичные результаты от запуска к запуску. В MT5-тестере - нет.

 
fxsaber:

В MT4 будет всегда возврат false, потому как без мусора - все нулями. В MT5 - true.

Это тест на то, что МТ4 заполняет массив нулями? Тогда надо иметь в виду, что если ArrayResize использует третий параметр с резервом, то последующие реаллокации в пределах резерва ничего не инициализируют. Будет мусор. Рекомендую делать явную инициализацию, чтобы потом случайно не удивляться, как в примере с оптимизацией, которая послужила толчком данному обсуждению.

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

 
Stanislav Korotky:

Это тест на то, что МТ4 заполняет массив нулями? Тогда надо иметь в виду, что если ArrayResize использует третий параметр с резервом, то последующие реаллокации в пределах резерва ничего не инициализируют. Будет мусор.

Не будет мусора.

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

Это не спасет

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2017.09.12 11:18

Даже если бы я писал идеально (не делая ошибок - а это не так), то нормальна ситуация, когда берешь чью-ту библиотеку (иногда без исходного кода - в Маркете) и используешь, надеясь, что она написана грамотно. И ничто не страхует от того, что после этого сам нарвусь на различные результаты в тестере. И найти истинную причину будет ОЧЕНЬ сложно. Исправить же - иногда невозможно.

Цель - чтобы от запуска к запуску результат был воспроизводим - идентичен, даже с ошибкой.

 
fxsaber:

Не будет мусора.



Тогда надо поправить документацию?

Инициализация массива выражением ArrayInitialize(array, init_val) не означает инициализацию этим же значением и элементов резерва, выделенного для этого массива. При последующих увеличениях размера массива array функцией ArrayResize() в пределах текущего резерва, в конец массива добавляются элементы, значения которых не определены и, чаще всего, не равны init_val.

 
Stanislav Korotky:

Тогда надо поправить документацию?

Инициализация массива выражением ArrayInitialize(array, init_val) не означает инициализацию этим же значением и элементов резерва, выделенного для этого массива. При последующих увеличениях размера массива array функцией ArrayResize() в пределах текущего резерва, в конец массива добавляются элементы, значения которых не определены и, чаще всего, не равны init_val.

Не надо, потому что в MT4-документации такого просто нет.


Наводит ужас мысль, что в какой-нибудь мат. библиотеке (Include\Math - 7 Мb исходников) не произведена инициализация в одном/двух местах! И как эту ошибку откопать, которая в MT5-тестере выдает разные одиночные прогоны, а в MT4 - одинаковые?

 
Stanislav Korotky:

Я видимо отстал от жизни. По мне так индикаторный буфер всегда имеет длину равную количеству баров. И отказ от его инициализации в МТ5 приводит к тому, что на экран выводится мусор. Получается, что явная инициализация обязательна. И зачем она просто напросто переложена с ядра (как было в МТ4) на программиста MQL - не понятно. Реальных доводов о том, что как-то можно ускориться не делая инициализации и при этом не получить отображения мусора, я не видел.

Про пользовательский динамический массив я ничего не говорю - там действительно действует правило: тот кто его аллоцировал, тот и ответственен за правильную чистку. ArrayInitialize во многих случаях полезен. Это не вопрос быстродействия, а корректности работы программы. Расставьте приоритеты: быстро и/или правильно. Обычно некоторые проверки на правильность и подготовка данных требуют дополнительных расходов по времени (хоть и минимальных), но без этого никуда - чудес не бывает.

Вы не обратили внимание на фразу

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Viktorov, 2017.09.12 10:50

Давайте возьмём к примеру массив буфер индикатора: При инициализации индикатора буфер имеет нулевую длину. Что там инициализировать нулями? При добавлении очередного индекса его принудительно обнулять и потом заполнять каким-то значением??? Для чего это обнуление или заполнение EMPTY_VALUE? А если есть необходимость назначить PLOT_EMPTY_VALUE и не 0 и не EMPTY_VALUE или принудительно одно, а надо другое... Как ни крути получается лишняя трата времени...

А пользовательский массив... Массив-то объявляется для каких-то данных отличных от нуля и EMPTY_VALUE. Так с какой целью его принудительно инициализировать чем-то?

Вот и получается, что на быстродействие в большинстве случаев сказывается.



А уже в OnCalculate это делать бессмысленно. Какой резон чем-то инициализировать массив и тут-же его заполнять какими-то значениями из формулы? При добавлении бара, соответственно и ячейки массива, какой смысл его заполнять чем-то и сразу-же значением из формулы или пустым значением?

 
Alexey Viktorov:

А уже в OnCalculate это делать бессмысленно. Какой резон чем-то инициализировать массив и тут-же его заполнять какими-то значениями из формулы? При добавлении бара, соответственно и ячейки массива, какой смысл его заполнять чем-то и сразу-же значением из формулы или пустым значением?

Инициализируются только новые элементы массива. А смысл все тот же - идентичность результатов от запуска к запуску, даже если в коде ошибка (часто не своя). Пример с мат. библой привел выше.

Мусор - зло.

 
fxsaber:

Не надо, потому что в MT4-документации такого просто нет.

А откуда я это взял тогда? Ходим сюда.

ArrayInitialize - Операции с массивами - Справочник MQL4
ArrayInitialize - Операции с массивами - Справочник MQL4
  • docs.mql4.com
ArrayInitialize - Операции с массивами - Справочник MQL4
 
Stanislav Korotky:

А откуда я это взял тогда? Ходим сюда.

Так там речь идет не про ArrayResize, а про ArrayInitialize. ArrayResize гарантирует забивание нулями в MT4.


Для интереса посмотрел во всех своих исходниках под MT5, насколько часто использую ArrayInitialize. Единицы раз. Похоже, меньше процента всех динамических массивов. А там, где использовал, нужно было специально забить нулями, поэтому вместо for использовал запись покороче.

Причина обращения: