Errors, bugs, questions - page 2676

 
Sergey Dzyublik:

MT5 (build 2347) Why such a big overhead when adding one element at a time to an array using ArrayResize, if memory has been reserved for them in advance?

Please consider improving the internal reservation algorithm with ArrayResize.

For example, for classes we can assume that they perform some kind of "internal registering in lists" in addition to calling the constructor.
And within the framework of reservation with ArrayResize, apart from direct memory allocation, you can try to optimize the process:
- take data from the adjacent created element (e.g. pointer to a virtual function table);
- pre-execute or reserve space for "internal registration" of classes that have not yet been created;

Thanks for the message.

The ArrayResize code is protected from being called empty (when there is no change in the number of elements), so the function code does not work.

Whereas a real change in the number of elements triggers one or the other part of the ArrayResize function, depending on the array


Thanks to the code you presented, I was able to reduce the complexity of one part of ArrayResize to zero, this will speed up the function for arrays of objects
 
Ilyas:

Can you tell me how to reduce the memory consumption of the terminal? When I run an EA, I request a few million ticks. I make calculations on them and don't need them anymore. I only use tick functions to load fresh ticks so there are no gaps.


Because of those million ticks the terminal consumes 500 Mb of memory and doesn't hurry to free it. To be more exact, it simply doesn't free it. Is it possible to force Terminal to clear all its caches to minimize consumption? For a VPS, 0.5 GB per terminal is too much.

 
fxsaber:

Can you tell me how to reduce the memory consumption of the terminal? When I run an EA, I request a few million ticks. I make calculations on them and don't need them anymore. I only use tick functions to load fresh ticks so there are no gaps.


Because of those million ticks the terminal consumes 500 Mb of memory and doesn't hurry to free it. To be more exact, it simply doesn't free it. Is it possible to force Terminal to clear all its caches to minimize consumption? For VPS, 0.5 GB per terminal is too much.

ArrayFree

If your program needs to manage memory in complex dynamic environments, the ArrayFree() function allows you to explicitly and immediately free memory occupied by a dynamic array which is no longer needed.

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

ArrayFree

Free, of course. The terminal itself stores ticks in its cache, which I don't need during operation.

It's better for me to raise these ticks again when I'm cold. I need a mechanism to "cool down" the Terminal.

 

Hello, encountered a problem that CopyTicks and CopyTicksRange in the tester can't get data from other tools... When added to the chart, everything works.

Build 2363 (and the same was on 2361)

May I have made a mistake? Please help, thank you!

#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;
}
Files:
terminal.png  59 kb
tester.png  25 kb
tester_log.png  41 kb
 
LittleBitTime:

Hello, encountered a problem that CopyTicks and CopyTicksRange in the tester can't get data from other tools... When added to the chart, everything works.

Build 2363 (and the same was on 2361)

May I have made a mistake? Please help, thank you!

CopyTicks does not initiate a data upload in the tester

Request CopyRates of the desired instrument first. At least 1 bar. Then pumping and generation of tick sequence will take place.

After that, quietly request ticks

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

Thanks for the message.
The ArrayResize code has protection against an empty call (when there is no change in the number of elements), so the function code does not work.
Whereas a real change in the number of elements, triggers one or the other part of the ArrayResize function, depending on the array

Thanks to the code you presented, I managed to reduce the complexity of one part of ArrayResize to zero, this will speed up the function for arrays of objects

Good afternoon, thank you very much.
I haven't used the new operator before, as it should be slower by logic than ArrayResize with reserved memory.
But I'm impressed with the results obtained, it turns out that it's vice versa, the native array via new operator is faster.

MT5 (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 does not initiate a data upload in the tester

Request CopyRates of the desired instrument first. At least 1 bar. Then pumping and generation of tick sequence will take place.

After that, quietly request ticks

Thank you very much, that helped. I couldn't find it in the documentation... Or didn't I look hard enough? It wouldn't be a bad thing to write about it there :)
 
LittleBitTime:
Thank you very much, it helped. I couldn't find it in the documentation... Or I searched badly? It would be good to write about it there :)

It would be better to make automatic uploads like on CopyRates.

 

Cleaned up the list of "old" inactive agents in my profile yesterday

A day later I go to the profile and see that the list of agents has been restored to the entries that were deleted.

And the date of creation and activity of agents has been changed

There is an assumption (possibly erroneous) that the list is restored after viewing agent statistics on cloud.mql5.com