Я взял реальную задачу, когда в конце бэктеста нужно посчитать длительность всех позиций. Сохранил Open/Close-время позиций в массив. И прогнал на нем следующий скрипт.
В подобных задачах нужен только однократный проход по всем позициям, поэтому не удалось получить преимущество через кеширование. Наверное, тут могут помочь только вшитые в код до компиляции табличные данные. Но бороться за половину миллисекунды, наверное, не стоит. Спасибо за исследование!
Я взял реальную задачу, в которой по итогам бэктеста мне нужно было рассчитать продолжительность всех позиций. Я сохранил время открытия и закрытия позиций в массиве. Затем я запустил на нем следующий скрипт.
Прилагаемый файл «Time.bin» содержит 324 865 позиций, из которых 324 425(99,87 %) имеют короткую продолжительность < 24 часа (не охватывают выходные и праздничные дни).
Для объективного сравнения увеличьте долю позиций с более длительной продолжительностью, и вы увидите реальное повышение эффективности благодаря моим оптимизациям.
Прилагаемый файл «Time.bin» содержит 324 865 позиций, из которых 324 425(99,87 %) имеют короткую продолжительность < 24 часа (не охватывают выходные и праздничные дни).
Для объективного сравнения увеличьте долю позиций с более длительной продолжительностью, и вы увидите реальное повышение эффективности благодаря моим оптимизациям.
К сожалению, при проведении симуляции даты и времени я обнаружил, что ни одна из более быстрых замен для StructToTime() и TimeToStruct(), опубликованных ранее здесь и здесь, не работала корректно для лет после 2100 года.
Мне пришлось переработать реализации, чтобы устранить эту проблему, и теперь они корректно работают для всех лет.
Кроме того, удалось добиться значительного повышения производительности (благодаря некоторым микрооптимизациям, таким как использование беззнакового деления и модуля).
Альтернатива функции StructToTime() на языке MQL:
datetimeStructToTimeFast(constMqlDateTime& st)
{
constuint j = st.mon < 3;
constuint y = st.year - j;
constuint m = j ? st.mon + 12 : st.mon;
constuint f = (979 * m - 2918) / 32; // количество дней до начала месяцаconstuint n = st.day + f + 365*y + (y/4) - (y/100) + (y/400) - 306 - 719163;
return (datetime)n*86400 LL + st.hour*3600 + st.min*60 + st.sec;
}
Замена функции TimeToStruct() в MQL:
boolTimeToStructFast(datetime time, MqlDateTime& dt_struct)
{
uint n = (uint)(time / 86400 ULL) ; // День Unixuint N = n + 12699422 ; // Расчетный календарный деньuint a = 4 * N + 3 ; // N_1uint c = a / 146097 ; // векuint e = a % 146097 / 4 ; // [0, 36524] — день векаuint b = 4 * e + 3 ; // N_2uint z = b / 1461 ; // [0, 99] - год векаuint h = b % 1461 / 4 ; // [0, 365] — количество дней с 1 мартаuint d = 2141 * h + 197913 ; // N_3uint M = d / 65536 ; // [3, 14] — Месяцuint D = d % 65536 / 2141 ; // [0, 30] — Деньuint Y = 100 * c + z ; // Годuint J = h >= 306 ; // янв-февuint l = z ? (z % 4 == 0) : (c % 4 == 0) ; // isLeapuint sec = (uint)(time - n * 86400 ULL);
dt_struct.year = (int)(Y - 32800 + J);
dt_struct.mon = (int)(J ? M - 12 : M);
dt_struct.day = (int)(D + 1);
dt_struct.hour = (int)(sec / 3600);
dt_struct.min = (int)((sec / 60) % 60);
dt_struct.sec = (int)(sec % 60);
dt_struct.day_of_week = (int)((n + 4) % 7);
dt_struct.day_of_year = (int)(h + (J ? -306 : 59 + l));
return (true);
}
The discussion revolves around the performance of a function in different compiler versions and optimization settings. It highlights the variability in results due to compiler optimizations, the unreliability of certain benchmarks, and the impact of code modifications on performance. The author notes that the function's behavior is influenced by factors like the compiler version, optimization levels, and the presence of specific code elements, making it difficult to draw definitive conclusions. The function is considered unreliable and may be removed from benchmarks due to its inconsistent performance across different environments.
Это алгоритмическое решение проблемы обработки чередующихся последовательностей, нарушаемых нерегулярными событиями, такими как високосные годы и столетние годы. Помимо обеспечения корректного преобразования дат для всех лет, данный подход демонстрирует общий метод, который можно повторно использовать для решения аналогичных задач, связанных с в остальном регулярными последовательностями, содержащими периодические исключения.
Лежащая в основе идея полезна для финансовых рынков — торговые циклы, которые следуют за обычными рабочими днями, но пропускают выходные и рыночные праздники.
Иногда могу открыть/закрыть.
Считаю, что 5/6 результатов ниже правильные.
Я считаю, что 5 из 6 приведенных ниже результатов верны.
Исправление:
Результат:
Исправление:
Да, теперь совпадает.
Я взял реальную задачу, когда в конце бэктеста нужно посчитать длительность всех позиций. Сохранил Open/Close-время позиций в массив. И прогнал на нем следующий скрипт.
В подобных задачах нужен только однократный проход по всем позициям, поэтому не удалось получить преимущество через кеширование. Наверное, тут могут помочь только вшитые в код до компиляции табличные данные. Но бороться за половину миллисекунды, наверное, не стоит. Спасибо за исследование!
ЗЫ Благодаря Вам обнаружил у себя ошибку.
Еще раз спасибо.Я взял реальную задачу, в которой по итогам бэктеста мне нужно было рассчитать продолжительность всех позиций. Я сохранил время открытия и закрытия позиций в массиве. Затем я запустил на нем следующий скрипт.
Прилагаемый файл «Time.bin» содержит 324 865 позиций, из которых 324 425 (99,87 %) имеют короткую продолжительность < 24 часа (не охватывают выходные и праздничные дни).
Для объективного сравнения увеличьте долю позиций с более длительной продолжительностью, и вы увидите реальное повышение эффективности благодаря моим оптимизациям.
Прилагаемый файл «Time.bin» содержит 324 865 позиций, из которых 324 425 (99,87 %) имеют короткую продолжительность < 24 часа (не охватывают выходные и праздничные дни).
Для объективного сравнения увеличьте долю позиций с более длительной продолжительностью, и вы увидите реальное повышение эффективности благодаря моим оптимизациям.
Результат.
Чем больше это слагаемое, тем быстрее вариант с кэшем.
P.S. Благодаря вам я обнаружил ошибку в своём собственном коде.
Ещё раз спасибо.Тест:
Добрый день,
К сожалению, при проведении симуляции даты и времени я обнаружил, что ни одна из более быстрых замен для StructToTime() и TimeToStruct(), опубликованных ранее здесь и здесь, не работала корректно для лет после 2100 года.
Мне пришлось переработать реализации, чтобы устранить эту проблему, и теперь они корректно работают для всех лет.
Кроме того, удалось добиться значительного повышения производительности (благодаря некоторым микрооптимизациям, таким как использование беззнакового деления и модуля).
Альтернатива функции StructToTime() на языке MQL:
Замена функции TimeToStruct() в MQL:
Тесты производительности:
не работала корректно для лет после 2100 года
Я извиняюсь, но сейчас 2026, а вот к 2100 скорее всего о терминале МТ5 не останется в интернете даже воспоминаний.
Зачем всё это?
В чём смысл всего этого?
Высокопроизводительные функции работы со временем, действующие для всего диапазона дат и времени MQL5 (с 1 января 1970 года по 31 декабря 3000 года):
(На основе алгоритма преобразования календарей Нери–Шнайдера: здесь)
Прилагаемый файл скрипта содержит исходные коды и полные проверки.