Ответ 1
Не могли бы вы использовать DateTime.UtcNow и преобразовать только в локальное время, когда данные будут представлены? Вы уже определили, что DateTime.UtcNow намного быстрее, и он устранит любую двусмысленность вокруг DST.
Мы с коллегой по этому вопросу идем вперед и назад, и я надеюсь получить некоторые внешние мнения относительно того, является ли мое предлагаемое решение хорошей идеей.
Во-первых, отказ от ответственности: я понимаю, что понятие "оптимизация DateTime.Now
" кажется сумасшедшим для некоторых из вас. У меня есть пара упреждающей защиты:
DateTime.Now
медленный (относительно говоря). Метод ниже быстрее.Теперь на вопрос.
В принципе, из тестов мы обнаружили, что DateTime.Now
занимает примерно 25 тиков (около 2,5 микросекунд) для запуска. Разумеется, это составляет от тысячи до миллионов звонков. Похоже, что первый звонок на самом деле занимает значительное количество времени, а последующие вызовы намного быстрее. Но все же, 25 тиков являются средними.
Однако мой коллега и я заметили, что DateTime.UtcNow
занимает значительно меньше времени для запуска - в среднем, всего 0,03 микросекунды.
Учитывая, что наше приложение никогда не будет работать, пока есть изменения в летнее время, мое предложение состояло в том, чтобы создать следующий класс:
public static class FastDateTime {
public static TimeSpan LocalUtcOffset { get; private set; }
public static DateTime Now {
get { return DateTime.UtcNow + LocalUtcOffset; }
}
static FastDateTime() {
LocalUtcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
}
}
Другими словами, при запуске определите смещение UTC для локального часового пояса один раз - и с этой точки вперед используйте скорость DateTime.UtcNow
, чтобы получить текущее время намного быстрее через FastDateTime.Now
.
Я мог видеть, что это проблема, если смещение UTC изменилось за время работы приложения (если, например, приложение работало в одночасье); но, как я уже сказал, в нашем случае этого не произойдет.
У моего коллеги есть другое представление о том, как это сделать, что слишком сложно для меня объяснить здесь. В конечном счете, насколько я могу судить, оба наших подхода возвращают точный результат, мой немного быстрее (~ 0,07 микросекунды против ~ 0,21 микросекунды).
Что я хочу знать:
FastDateTime.Now
безопасно?Не могли бы вы использовать DateTime.UtcNow и преобразовать только в локальное время, когда данные будут представлены? Вы уже определили, что DateTime.UtcNow намного быстрее, и он устранит любую двусмысленность вокруг DST.
Одно различие между результатом
DateTime.Now
и
DateTime.UtcNow + LocalUtcOffset
- значение свойства Kind - Local vs Utc соответственно. Если итоговое DateTime передается в стороннюю библиотеку, рассмотрите вопрос о возврате
DateTime.SpecifyKind(DateTime.UtcNow + LocalUtcOffset, DateTimeKind.Local)
Мне нравится ваше решение.
Я сделал несколько тестов, чтобы увидеть, насколько быстрее он сравнивается с обычным DateTime.Now
DateTime.UtcNow
в 117 раз быстрее, чем DateTime.Now
с использованием DateTime.UtcNow
достаточно хорош, если нас интересуют только продолжительность, а не время. Если все, что нам нужно, это вычисление продолжительности определенного раздела кода (выполнение duration= End_time - Start_time
), то часовой пояс не важен и DateTime.UtcNow
является достаточным.
Но если нам нужно время, то нам нужно сделать
DateTime.UtcNow + LocalUtcOffset
Просто добавление временного интервала немного замедляется
и теперь, согласно моим тестам, мы просто в 49 раз быстрее обычного DateTime.Now
Если мы поместим это вычисление в отдельную функцию/класс, как было предложено, то вызов метода замедляет нас еще больше и мы только в 34 раза быстрее.
Но даже в 34 раза быстрее много!
Короче говоря,
Использование DateTime.UtcNow
намного быстрее, чем DateTime.Now
Единственный способ улучшить предложенный класс - использовать
встроенный код: DateTime.UtcNow + LocalUtcOffset
вместо вызова метода класса
BTW пытается заставить компилятор компилироваться как встроенный с помощью [MethodImpl(MethodImplOptions.AggressiveInlining)]
казалось, не ускоряли ход событий.
Чтобы ответить в обратном порядке:
2) Я не могу придумать более быстрый способ.
1) Стоит ли проверять, есть ли какие-либо улучшения в конвейере, как они только что объявлено для System.IO
Трудно быть уверенным в безопасности, но это то, что кричит для многих модульных тестов. На ум приходит дневной свет. Система одна, очевидно, очень ожесточена, в то время как у вас нет.