Особенности языка mql5, тонкости и приёмы работы - страница 263

 
Nikolai Semko #:

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

Ну вот и разобрались. Всем спасибо, все свободны ))

 
Nikolai Semko #:

где здесь костыльность?

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

Выложите пожалуйста файл с окончательными версиями этих функций.

 

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

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

Andrey Dik, 2024.06.05 07:59

В справочнике по работе с функцией ArrayResize сказано следующее:

Примечание

Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в качестве индикаторных буферов функцией SetIndexBuffer(). Для индикаторных буферов все операции по изменению размера производит исполняющая подсистема терминала.

Общее число элементов в массиве не может превышать 2147483647.

При частом распределении памяти рекомендуется использовать третий параметр, задающий резерв для уменьшения количества физического распределения памяти. Все последующие вызовы функции ArrayResize не приводят к физическому перераспределению памяти, а только меняется размер первого измерения массива в пределах зарезервированной памяти. Следует помнить, что третий параметр будет использоваться только тогда, когда будет происходить физическое распределение памяти, например:

ArrayResize(arr,1000,1000);
for(int i=1;i<3000;i++)
   ArrayResize(arr,i,1000);

В данном случае произойдёт 2 перераспределения памяти, один раз до входа в цикл на 3000 итераций, при этом размерность массива будет установлена в 1000 и второй при i равной 2000. Если третий параметр опустить, то произойдёт 2000 физических перераспределения памяти и это замедлит выполнение программы.

Я ошибочно полагал, что при первом запуске функции третий параметр выделит память под массив:

ArrayResize (a, 0, 10000);

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

В моём случае нужно делать так:

ArrayResize (a, 10000, 10000);
ArrayResize (a, 0, 10000);

или так:

ArrayResize (a, 1, 10000);
ArrayResize (a, 0, 10000);

что является равнозначным, или так:

ArrayResize (a, 1, 10000);
ArrayResize (a, 0);

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


Таким образом, прошу разработчиков добавить в справку этот момент, что дополнительное выделение памяти под массив происходит только в случае ненулевого второго параметра.

Много времени потерял на выяснение причин тормозов, никак не мог представить, что проблема именно тут.


 
Artyom Trishkin #:

А как понять сколько памяти выделять в этой функции?

 
Vladimir Pastushak #:

А как понять сколько памяти выделять в этой функции?

Выделяется память под указанное количество ячеек массива. Другими словами - под указанный размер. А его мы примерно знаем при написании программы. Это дополнительный размер. 
В справке написано когда, и сколько раз происходит перераспределение памяти. 
 
Vladimir Pastushak #:

А как понять сколько памяти выделять в этой функции?

   Print(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));
   double arr[];
   ArrayResize(arr,1,1000000);
   Print(TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE));

Да, действительно, если второй параметр 1, то выделяется 8 Мб.
Если 0, то ничего не выделяется

 
В чём преимущество выделения большего объема и ресайса на каждой итерации с целью увеличения размера, по сравнению с вариантом создания максимального размера массива (что может понадобится) и ресайса его до нужного в конце цикла? Я в коде преимущественно использую второй вариант.
 
Aleksey Vyazmikin #:
В чём преимущество выделения большего объема и ресайса на каждой итерации с целью увеличения размера, по сравнению с вариантом создания максимального размера массива (что может понадобится) и ресайса его до нужного в конце цикла? Я в коде преимущественно использую второй вариант.

Ресайза не произойдет (физического перераспределения).

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

Новая версия платформы MetaTrader 5 build 4230: больше встроенных приложений и расширение поддержки ONNX

fxsaber, 2024.03.05 18:13

void OnStart()
{
  MqlTick Ticks[];
  
  ArrayResize(Ticks, 5e7);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
  
  ArrayResize(Ticks, 1);
  Print(MQLInfoInteger(MQL_MEMORY_USED)); // 2862
}
 
fxsaber #:

Ресайза не произойдет (физического перераспределения).

А какой в нём смысл, если может быть использован весь массив?

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

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

 
Aleksey Vyazmikin #:

А какой в нём смысл, если может быть использован весь массив?

Тиковый мультивалютный Тестер. Запрашиваете тики по одному символу (50% RAM), затем фильтруете их (10% RAM). Тоже самое по другим символам. Если в фильтре тики не ужимаются физически, то нехватка памяти на стадии подготовки данных.