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

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

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

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

fxsaber, 2025.01.22 11:09

Облако - tester_file.

#define FILENAME "Ticks.bin" // https://www.mql5.com/ru/forum/478178/page10#comment_55702486

#property tester_no_cache
#property tester_file FILENAME

input int inRange = 0;

double OnTester()
{
  MqlTick Ticks[];
  
  return(FileLoad(FILENAME, Ticks) ? ArraySize(Ticks) : -1);
}


Эффективность.

optimization finished, total passes 1000
optimization done in 0 minutes 30 seconds
shortest pass 0:00:00.078, longest pass 0:00:00.234, average pass 0:00:00.192
local 1000 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)

Какого черта следующее изменение ускоряет оптимизацию почти в три раза?!

#define FILENAME "Ticks.bin" // https://www.mql5.com/ru/forum/478178/page10#comment_55702486

#property tester_no_cache
#property tester_file FILENAME

input int inRange = 0;

MqlTick Ticks[2000000];

double OnTester()
{
//  MqlTick Ticks[];
  
  return(FileLoad(FILENAME, Ticks) ? ArraySize(Ticks) : -1);
}
optimization finished, total passes 1000
optimization done in 0 minutes 12 seconds
shortest pass 0:00:00.009, longest pass 0:00:00.114, average pass 0:00:00.080
local 1000 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)


Почему FileLoad в динамический массив работает медленнее, чем в статический?

 
fxsaber #:

Какого черта следующее изменение ускоряет оптимизацию почти в три раза?!


Почему FileLoad в динамический массив работает медленнее, чем в статический?

Предположу, что глобальный массив выделяется один раз, т.к. эксперт загружается единожды (если не была вызвана функция ExpertRemove).

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

 
Stanislav Korotky #:

Предположу, что глобальный массив выделяется один раз, т.к. эксперт загружается единожды (если не была вызвана функция ExpertRemove).

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

Жаль, что работа с данными в мат. режиме - больше теория, чем практика.

 
fxsaber #:

Почему FileLoad в динамический массив работает медленнее, чем в статический?

Думаю, просто не оптимальный резерв в ЭррейРесайз используется внутри FileLoad.

 
Andrey Khatimlianskii #:

Думаю, просто не оптимальный резерв в ЭррейРесайз используется внутри FileLoad.

template <typename T>
int FileLoad2( const string FileName, T &Data[] )
{
  int Res = -1;
  
  const int Handle = FileOpen(FileName, FILE_READ | FILE_BIN);
  
  if (Handle != INVALID_HANDLE)
  {
    Res = (int)FileReadArray(Handle, Data, 0, ArrayResize(Data, (int)FileSize(Handle) / sizeof(T)));
    
    FileClose(Handle);
  }
  
  return(Res);
}

Там все однозначно

 
Andrey Khatimlianskii #:

Думаю, просто не оптимальный резерв в ArrayResize используется внутри FileLoad.

Почему "не оптимальный"? У вас 1000 ArrayResize против 1 статического массива, это совершенно нормальный результат.
 
Alain Verleyen #:
Почему "не оптимальный"? У вас 1000 ArrayResize против 1 статического массива, это совершенно нормальный результат.

1000 ArrayResize должно занять 15 миллисекунд (так как мой тест показывает, что один ArrayResize занимает ~15 микросекунд)

void OnStart()
  {
   MqlTick Ticks[];
   ulong tickcount = GetMicrosecondCount();
   ArrayResize(Ticks, 2000000 + tickcount % 10);
   ulong spent = GetMicrosecondCount() - tickcount;
   Print("Time spent resizing array: ", spent, " microseconds");
   //--- Everything below is an attempt to avoid compiler optimizations
   for(int i = ArraySize(Ticks) - 1; i >= 0; i--)
     {
      int r = MathRand() % 5;
      Ticks[i].time = ++r;
      Ticks[i].bid = ++r * _Point;
      Ticks[i].ask = ++r * _Point;
      Ticks[i].last = ++r * _Point;
      Ticks[i].volume = ++r;
      Ticks[i].time_msc = ++r;
      Ticks[i].flags = ++r;
      Ticks[i].volume_real = ++r;
     }
   MqlTick sum;
   for(int i = ArraySize(Ticks) - 1; i >= 0; i--)
     {
      sum.time += Ticks[i].time;
      sum.bid += Ticks[i].bid;
      sum.ask += Ticks[i].ask;
      sum.last += Ticks[i].last;
      sum.volume += Ticks[i].volume;
      sum.time_msc += Ticks[i].time_msc;
      sum.flags += Ticks[i].flags;
      sum.volume_real += Ticks[i].volume_real;
     }
   Print(sum.time, sum.bid, sum.ask, sum.last, sum.volume, sum.time_msc, sum.flags, sum.volume_real);
  }
 
Vladislav Boyko #:

1000 ArrayResize должны занимать 15 миллисекунд (поскольку мой тест показывает, что один ArrayResize занимает ~15 микросекунд).

Это неверное рассуждение.
 
fxsaber #:

Жаль, что работа с данными в мат. режиме - больше теория, чем практика.

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

Сайт использует cookie-файлы. Узнайте больше о нашей политике по использованию cookie-файлов.