Мы с коллегой по этому вопросу идем вперед и назад, и я надеюсь получить некоторые внешние мнения относительно того, является ли мое предлагаемое решение хорошей идеей.
Во-первых, отказ от ответственности: я понимаю, что понятие "оптимизация 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
безопасно? - Может ли кто-нибудь еще подумать о еще более быстром способе получения текущего времени?