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

 
amrali #:

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

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

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

Реализовали в билде 6002, доступно на MetaQuotes-Demo

2026.07.14 00:14:42.467 StructToTimeFast (GBPUSD,H1)    Compiler Version: 6002, AVX2 + FMA3
2026.07.14 00:14:42.468 StructToTimeFast (GBPUSD,H1)    AMD RYZEN AI MAX+ 395 w/ Radeon 8060S, AVX512 + FMA3
2026.07.14 00:14:42.620 StructToTimeFast (GBPUSD,H1)     1.03 ns, checksum = 323500114770647190  /// MQL's StructToTime()
2026.07.14 00:14:42.641 StructToTimeFast (GBPUSD,H1)     1.06 ns, checksum = 323500114770647190   // StructToTimeFast


2026.07.14 00:17:37.406	TimeToStructFast (GBPUSD,H1)	1970.01.01 00:23:41 - 2999.12.31 23:28:37
2026.07.14 00:17:37.538	TimeToStructFast (GBPUSD,H1)	 6.57 ns, checksum = 6236374825958545665  /// MQL's TimeToStruct()
2026.07.14 00:17:37.582	TimeToStructFast (GBPUSD,H1)	 2.19 ns, checksum = 6236374825958545665   // TimeToStructFast

Даже обогнали в первом случае.

Спасибо за пример!

 
Renat Fatkhullin #:

Реализовали в билде 6002, доступно на MetaQuotes-Demo

Даже обогнали в первом случае.

Спасибо за пример!

Impressive!

Thank you.

 
Renat Fatkhullin #:
Реализовали в билде 6002
Ещё-бы с iBarShift(...) что-то сделать, функция часто применяемая.
 
Renat Fatkhullin # :

Implemented in build 6002, available on MetaQuotes-Demo

They even overtook us in the first case.

Thanks for the example!

My TimeToStruct is faster!  

I use unsigned types for max optimization of div/mod (here).

also, I take modulo time by subtraction: 

   uint sec = (uint)(time - n * 86400 ULL);
Оптимизация работы с временем для всех лет и улучшение производительности.
Оптимизация работы с временем для всех лет и улучшение производительности.
  • 2026.06.18
  • www.mql5.com
Пользователь описывает работу с временными данными в MQL5, включая исправление ошибок, оптимизацию скриптов и тестирование производительности. Он упоминает проблемы с преобразованием дат после 2100 года, а также методы улучшения эффективности с использованием кэширования и микрооптимизаций. Также он делится результатами тестов и предлагает алгоритмическое решение для обработки регулярных последовательностей с исключениями, применимое для финансовых рынков.
 
Dominik Egert #:

Я это понимаю и знаю о «общественном достоянии». Спасибо.

Так как же мне это понимать:


Может быть, мне стоит открыть новую ветку для этого обсуждения.

Точный текст формулировки:

Предоставляется ограниченное, неисключительное разрешение на:

    • использовать, копировать и модифицировать Программное обеспечение дляличного использования, как коммерческого, так и некоммерческого, без предварительного разрешения.

Существует принцип юридического толкования expressio unius est exclusio alterius, означающий, что упоминание одного исключает другое. Следовательно, полный отказ от прав, который вы уже получили непосредственно от создателя произведения, разрешает вам совершать любые действия как личного, так и коммерческого характера. Это имеет место даже несмотря на то, что в данном документе не обсуждается способ предоставления разрешения. Повторим: термин «общественное достояние» термоядерным образом уничтожил всю защиту интеллектуальной собственности — включая защиту Algo Forge.

 
amrali #:

My TimeToStruct is faster!  

I use unsigned types for max optimization of div/mod (here).

also, I take modulo time by subtraction: 

Да, но ваша версия не проверяет значение и всегда возвращает true.

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

Если добавить проверку параметра в TimeToStructFast и изменить код теста, 
bool TimeToStructFast(datetime time, MqlDateTime& dt_struct)
  {
   if(time<0 || time>=91674063532800)
      return(false);
...
   datetime t[];
   ArrayResize(t, BENCHSIZE);
   for(int i = 0;i<BENCHSIZE;i++) {
      t[i] = i;
   }

то результат в биоде 6002 будет таким
2026.07.14 11:40:34.104 TimeToStructFast (EURUSD,H1)    Compiler Version: 6002, AVX2 + FMA3
2026.07.14 11:40:34.104 TimeToStructFast (EURUSD,H1)    AMD Ryzen 9 7950X 16-Core, AVX512 + FMA3
2026.07.14 11:40:34.142 TimeToStructFast (EURUSD,H1)    1970.01.01 00:00:00 - 1970.08.20 11:33:19
2026.07.14 11:40:34.206 TimeToStructFast (EURUSD,H1)     3.19 ns, checksum = 4186118827073392896  /// MQL's TimeToStruct()
2026.07.14 11:40:34.315 TimeToStructFast (EURUSD,H1)     5.43 ns, checksum = 4186118827073392896   // TimeToStructFast

Я считаю, что правильнее изменить контракт TimeToStruct
void TimeToStruct(datetime time, MqlDateTime& st);
и добавить отдельную функцию проверки времени.
bool IsValidTimeValue(datetime time);
Т.к. только разработчик(потребитель) знает о качестве исходных данных и необходимости валидации значений.
 
Ilyas #:
Да, но в вашей версии не производится проверка значения, и она всегда возвращает true.

1. Приятно знать, что числа были получены с включенной проверкой параметров. В любом случае, версия на C++ должна работать быстрее.

2. Согласен, что проверка параметра внутри функции — лишний шаг. Никто не проверяет возвращаемое значение TimeToStruct, так как источником входных данных является терминал. IsValidTime() — очень разумный выбор.

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

Почему не так?

if ((ulong)time >= 9167406353280)
 
amrali #:
3. Рост производительности (особенно в тестере стратегий) благодаря этим оптимизированным функциям впечатляет. Спасибо.
Для Тестера стратегий быстрая TimeToStruct должна запоминать значения предыдущего вызова. Тогда должно быть еще быстрее.
 

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

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

fxsaber, 2022.06.19 16:17

Для частного случая, когда для сортировки берется числовое поле (самая частая ситуация), написал вариант, который быстрее предыдущего на несколько порядков. Но при этом потребляет памяти в два раза больше. Актуально для больших массивов.


Результат.

Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 129 in OnStart: SortOnField_Num::SORT::Sort(Array)] = 34574468 mcs.

Alert: Bench_Stack = 0, 100 <= Time[Test9.mq5 130 in OnStart: SortOnField_Num::SORT2::Sort(Array)] = 10586 mcs.
Похоже, причина такого результата в том, что перемещать большие структуры между друг другом гораздо дороже во время сортировки, чем оперировать с индексами.