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

 
amrali #:

Высокопроизводительные функции работы со временем, действующие для всего диапазона дат и времени MQL5 (с 1 января 1970 года по 31 декабря 3000 года):

(На основе алгоритма преобразования календарей Нери–Шнайдера: здесь)

Прилагаемый файл скрипта содержит исходные коды и полные проверки.

Что такое ULL и U ?
 
Vladimir Pastushak #:
Что такое ULL и U?

  • Суффикс U: unsigned int 32 (uint)
  • Суффикс ULL: unsigned long 64 (ulong)

Эти беззнаковые делители (3600ULL, 86400ULL и т. д.) принудительно запускают беззнаковое деление и вычисление остатка по модулю, особенно когда числитель имеет тип datetime ( внутренне обрабатываемый как signed long 64).

Перед выполнением деления или вычисления модуля значение datetime будет преобразовано в ulong. Это обеспечивает более быструю оптимизацию со стороны компилятора.

datetime / 86400 ULL is a bit faster than datetime / 86400.

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

Проверьте это на сайте https://godbolt.org/


Compiler Explorer
Compiler Explorer
  • Matt Godbolt
  • godbolt.org
Compiler Explorer is an interactive online compiler which shows the assembly output of compiled C++, Rust, Go (and many more) code.
 

Подписанные и неподписанные операции div/mod:

int DayOfWeek(const datetime t)
  {
   return (int)(t / 86400 + THURSDAY) % 7;
  }

int DayOfWeekU(const datetime t)
  {
   return (int)((t / 86400 ULL + THURSDAY) % 7 U);
  }

#define  BENCHSIZE 10000000

ulong randUlong() { return((ulong)rand()<<60)|((ulong)rand()<<45)|((ulong)rand()<<30)|((ulong)rand()<<15)|(ulong)rand(); }

void OnStart() {
   Print("\nCompiler Version: " + (string)__MQLBUILD__ + ", " + __CPU_ARCHITECTURE__);
   Print(TerminalInfoString(TERMINAL_CPU_NAME) + ", " + TerminalInfoString(TERMINAL_CPU_ARCHITECTURE));

   datetime t[];
   ArrayResize(t, BENCHSIZE);
   for(int i = 0; i < BENCHSIZE;i++) {
      t[i] = (datetime) (randUlong() % D'3000.01.01');
   }

   // Тесты
   ulong sum = 0;
   ulong tt = GetMicrosecondCount();
   for(int i=0; i<BENCHSIZE; i++) { sum += t[i] + DayOfWeek(t[i]); }
   PrintFormat("%5.2f ns, checksum = %llu   // DayOfWeek", (GetMicrosecondCount()-tt)*1000.0/BENCHSIZE, sum);

   sum = 0;
   tt = GetMicrosecondCount();
   for(int i=0; i<BENCHSIZE; i++) { sum += t[i] + DayOfWeekU(t[i]); }
   PrintFormat("%5.2f ns, checksum = %llu   // DayOfWeekU", (GetMicrosecondCount()-tt)*1000.0/BENCHSIZE, sum);
  }

Результаты:

 Compiler Version: 5836, AVX2 + FMA3
 13 th Gen Intel Core i7-13700 KF, AVX2 + FMA3
  1.24 ns, checksum = 162509975528847278   // День недели
  0.72 ns, checksum = 162509975528847278   // DayOfWeekU