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

 
Sergey Dzyublik:

МТ5 (build 2347) Почему такой большой overhead при добавлении по одному элементу в массив с помощью ArrayResize, если память для них была заранее зарезервирована?

Прошу рассмотреть возможность улучшения внутреннего алгоритма резервирования с помощью ArrayResize.

Например, для классов можно припустить, что они кроме вызова конструктора выполняют некую "внутреннюю регистрацию в списках".
И в рамках резервирования с помощью ArrayResize, кроме непосредственного выделения памяти, можно попробовать оптимизировать процесс:
- брать данные из соседнего созданного элемента (например указатель на таблицу виртуальных функций);
- заранее выполнять или резервировать место под "внутреннюю регистрацию" классов, которые еще не созданы;

Спасибо за сообщение.

Код ArrayResize имеет защиту от пустого вызова (когда нет изменения количества элементов), поэтому код функции не отрабатывает.

Тогда как реальное изменение количества элементов, заставляет сработать ту или часть функции ArrayResize, в зависимости от массива


Благодаря представленному Вами коду, мне удалось свести сложность одной из частей ArrayResize к нулю, это ускорит работу функции для массивов объектов
 
Ilyas:

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


Терминал из-за этого миллиона тиков потребляет 500 Мб памяти и освобождать не торопится. Точнее, просто не освобождает. Возможно ли как-то принудить Терминал почистить все свои кеши, чтобы минимизировать потребление? Для VPS 0.5 Гб на каждый Терминал - жирно выходит.

 
fxsaber:

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


Терминал из-за этого миллиона тиков потребляет 500 Мб памяти и освобождать не торопится. Точнее, просто не освобождает. Возможно ли как-то принудить Терминал почистить все свои кеши, чтобы минимизировать потребление? Для VPS 0.5 Гб на каждый Терминал - жирно выходит.

ArrayFree

Если в программе необходимо самостоятельно управлять памятью в сложных динамических условиях, то функция ArrayFree() позволит явным образом и немедленно освобождать память, занятую ненужным уже динамическим массивом.

Документация по MQL5: Операции с массивами / ArrayFree
Документация по MQL5: Операции с массивами / ArrayFree
  • www.mql5.com
//| Класс диалога для работы с памятью                               | //| Освобождение памяти текущего массива                             | //| Попытка добавления памяти для текущего массива                   | //| Обработка событий                                                |...
 
Slava:

ArrayFree

Освобождаю, конечно. Сам терминал в кеше у себе хранит тики, которые мне не нужны во время работы.

Мне лучше потом на холодную эти тики снова поднять. Нужен механизм "остывания" Терминала.

 

Здравствуйте, столкнулся с проблемой, что CopyTicks и CopyTicksRange в тестере не могут получить данные у других инструментов.. При добавлении на график, все работает.

Билд 2363 (и на 2361 тож самое было)

Может я ошибку допустил? Прошу помощи, спасибо!

#property copyright "Copyright 2020, LittleBitTime"
#property link      "https://login.mql5.com/ru/users/LittleBitTime"
#property version   "1.00"

int OnInit() {
   return INIT_SUCCEEDED;
}

void OnDeinit(const int reason) {
}

void OnTick() {
   MqlTick LastTick;
   if (SymbolInfoTick(Symbol(), LastTick)) {
      //Print("START");
      
      if (GetTicks("RTS-3.20", LastTick.time_msc) && GetTicks("RTS-6.20", LastTick.time_msc)) {
         Print("История загружена");
      } else {
         Print("Ошибка загрузки истории");
      }
      //Print("END");
   } else {
      Print("Ошибка получения последнего тика, для получения последнего известного времени");
   }
}

bool GetTicks(string symbol, ulong TimeEnd) {
   ulong TimeStartPeriod = TimeEnd-(60*1000);
   
   MqlTick ticks[];
   bool success = false; //флаг успешного выполнения копирования тиков
   uint start = GetTickCount(); //замерим время старта перед получением тиков
   
   int received = CopyTicksRange(symbol, ticks, COPY_TICKS_ALL, TimeStartPeriod, TimeEnd);
   if (received != -1) {
      //выведем информацию о количестве тиков и затраченном времени времени
      PrintFormat("%s: received %d ticks in %d ms", symbol, received, GetTickCount()-start);
      //если тиковая история синхронизирована, то код ошибки равен нулю
      if (GetLastError() == 0)
         success = true;
      else
         PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d", symbol, received, GetTickCount()-start, _LastError);
   }
   
   if (!success) {
      PrintFormat("Ошибкаp загрузки тиков! " + symbol);
      
      return false;
   }
   
   
   return true;
}
Файлы:
terminal.png  59 kb
tester.png  25 kb
tester_log.png  41 kb
 
LittleBitTime:

Здравствуйте, столкнулся с проблемой, что CopyTicks и CopyTicksRange в тестере не могут получить данные у других инструментов.. При добавлении на график, все работает.

Билд 2363 (и на 2361 тож самое было)

Может я ошибку допустил? Прошу помощи, спасибо!

CopyTicks не инициирует закачку данных в тестере

Запросите сначала CopyRates нужного инструмента. Хотя бы 1 бар. Тогда произойдёт закачка и генерация тиковой последовательности.

После этого спокойно запрашивайте тики

Основы тестирования в MetaTrader 5
Основы тестирования в MetaTrader 5
  • www.mql5.com
Идея автоматической торговли привлекательна тем, что торговый робот может без устали работать 24 часа в сутки и семь дней в неделю. Робот не знает усталости, сомнений и страха,  ему не ведомы психологические проблемы. Достаточно четко формализовать торговые правила и реализовать их в виде алгоритмов, и робот готов неустанно трудиться. Но прежде...
 
Ilyas:

Спасибо за сообщение.
Код ArrayResize имеет защиту от пустого вызова (когда нет изменения количества элементов), поэтому код функции не отрабатывает.
Тогда как реальное изменение количества элементов, заставляет сработать ту или часть функции ArrayResize, в зависимости от массива

Благодаря представленному Вами коду, мне удалось свести сложность одной из частей ArrayResize к нулю, это ускорит работу функции для массивов объектов

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

МТ5 (build 2363):

#define K 1000
#define M (1000 * K)

#define   SpeedTest(test_count,msg,EX)        {uint mss=GetTickCount(); ulong count=test_count;for(ulong ii=0;ii<count&&!_StopFlag;ii++){EX;} \
                                              printf("%-60s: loops=%i ms=%u",msg,count,GetTickCount()-mss);}
                                              
class A{
public:
   int data;
};


template<typename T>
void test1(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize all",
   {
      T class_array[];
      ArrayResize(class_array, array_size);
   }
   )
};

template<typename T>
void test2(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with reserved memory",
   {
      T class_array[];
      ArrayResize(class_array, 1, array_size - 1);
      for(int i = 2; i <= array_size; i++){
         ArrayResize(class_array, i);
      }
   }
   )
};

template<typename T>
void test3(const int test_count, const int array_size){
   SpeedTest(
   test_count,"Test Class ArrayResize one by one with new operator",
   {
      T* class_array[];
      ArrayResize(class_array, array_size);
      for (int i = 0; i < array_size; ++i){
         class_array[i] = new T();
      }
      for (int i = 0; i < array_size; ++i){
         delete class_array[i];
      }
   }
   )
};


void OnStart()
{
  const int test_count = 1*K;
  const int array_size = 25*K;  
  
   printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
   test1<A>(test_count, array_size);              // Avg time: release( 730) / debug( 830)
   test2<A>(test_count, array_size);              // Avg time: release(1540) / debug(1720)
   test3<A>(test_count, array_size);              // Avg time: release(1200) / debug(1470)
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
   test1<A>(test_count, array_size);
   test2<A>(test_count, array_size);
   test3<A>(test_count, array_size);
}
  
 
Slava:

CopyTicks не инициирует закачку данных в тестере

Запросите сначала CopyRates нужного инструмента. Хотя бы 1 бар. Тогда произойдёт закачка и генерация тиковой последовательности.

После этого спокойно запрашивайте тики

Спасибо большое, помогло. А в документации этого я не нашел.. Или плохо искал? Не плохо было бы об этом там написать :)
 
LittleBitTime:
Спасибо большое, помогло. А в документации этого я не нашел.. Или плохо искал? Не плохо было бы об этом там написать :)

Лучше сделать автоматическую закачку как по CopyRates.

 

Почистил вчера в профиле список "старых" неактивных агентов

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

Причем, изменена дата создания и активности агентов

Есть предположение(возможно ошибочное), что список восстанавливается после просмотра статистики агентов на cloud.mql5.com