#.net #sql #date
#.net #sql #Дата
Вопрос:
Мысли:
Я полагаю, что в .NET базовая математика с датами выполняется с помощью тиков. Если бы это было так, я бы подумал, что не имеет значения, насколько далеки две даты при определении разницы между ними. Вы бы просто вычли тики, а затем выполнили серию делений, чтобы преобразовать результат из тиков в дни. Я не понимаю, как две более близкие даты ускорят это или как дальнейшие даты замедлят это. Я что-то упускаю?
На стороне SQL……Понятия не имею. Я предполагаю, что это похоже, но у меня нет доказательств этого.
Пример / Контекст:
Допустим, у меня есть функция, которая, если задать начальную дату, конечную дату и период времени (в днях для этого примера), сообщит мне, сколько раз этот период может встречаться в заданном диапазоне дат.
somefunction(<first of this year>, <first of last year>, <30 days>)
//returns 12
Один (плохой) способ реализации этой функции — начать с начальной даты, затем продолжать добавлять период времени (например, 30 дней) и проверять, прошла ли ваша конечная дата. Однако это происходит медленнее, чем шире ваш диапазон дат.
Другой способ — выяснить, сколько дней находится в диапазоне дат, и разделить на количество дней в вашем периоде времени. В .NET вы можете вычесть начальную и конечную даты и получить TimeSpan
обратную. В SQL вы можете использовать эту DateDiff
функцию примерно для того же.
Мой вопрос заключается в том, страдают ли эти другие методы от той же проблемы, что и первый. В частности: было бы быстрее вычислить разницу между двумя близкими датами или это вообще не имеет никакого значения?
Редактировать: Почему я спросил об этом?
Действительно ли производительность для нахождения разницы между двумя датами была проблемой, с которой я столкнулся?
Да (со звездочкой). В одном из наших приложений производился расчет, который занимал 0,3 секунды (и обычно его приходилось выполнять 30 раз или около того). Пользователи были не в восторге, поэтому я попытался посмотреть, где мы могли бы ускорить процесс. Я проследил проблему до функции, целью которой было найти разницу между двумя датами. Вместо того, чтобы просто вычитать их, он перебирал все даты между началом и концом и сохранял текущую сумму … действительно. При переключении функции на простое использование вычитания (и date diff в SQL (в базе данных был аналогичный код)) Я видел, что были процессы, которые запускались каждую ночь, чтобы сгенерировать число ближе к сегодняшнему дню для использования в вычислениях. Я задал этот вопрос, чтобы узнать, есть ли смысл продолжать запускать эти процессы и использовать значение, которое они генерируют, или просто использовать исходную дату начала. Теперь я чувствую себя очень комфортно, останавливая эти процессы. Спасибо всем за ваши ответы.
Комментарии:
1. Являются ли вычисления разности дат ощутимым узким местом в вашем коде?
2. @Anthony Хотите верьте, хотите нет, да. В списке была гораздо более сложная версия функции example, и текущая реализация была первым (плохим) способом. Я изменил логику, чтобы использовать различия в датах, но существует много инфраструктуры, чтобы сделать первый метод более … производительным. Я надеялся, что смогу многое из этого убрать, но хотел быть абсолютно уверенным, что в этом больше нет необходимости.
3. @diceguyd30: если узкое место находится в . ЧИСТЫЙ код, мне было бы очень интересно узнать больше о том, что вы делаете, и как Noda Time справляется с этим. Напишите мне (или в список рассылки Noda Time), если вам интересно работать вместе над этим.
4. @JonSkeet Я бы с большей готовностью сказал, что узким местом была плохо спроектированная функция. Теперь, когда я переключил логику на использование второго метода, который я перечислил, он работает замечательно, и после того, как меня (справедливо) упрекнули за мой очевидный вопрос, я уверен, что в будущем у меня не возникнет проблем с производительностью с этой логикой.
Ответ №1:
Любая разумная платформа будет представлять время как некоторое количество единиц с определенной эпохи. В этом случае разница в дате — это просто вычитание. Следовательно, выполнение этой операции не зависит от того, насколько далеко друг от друга находятся операнды. Это верно для CLR и SQL Server.
Почему это имеет значение?
Комментарии:
1. Существовала функция, которая без необходимости выполняла множество вычислений дат (несколько сотен переходов за несколько лет с очень небольшим периодом времени несколько раз). Я изменил его, чтобы вместо этого использовать различия в датах, но у нас было много устаревшей инфраструктуры, задачей которой было попытаться сузить даты, по которым проходила функция. Прежде чем я удалил эту инфраструктуру, я хотел убедиться, что нет никаких причин держать ее здесь.
2. Это предполагает, что вы говорите о «единицах измерения» с постоянной длиной. Сколько точно длится месяц? (В примере использовались дни, но это не всегда так.)
Ответ №2:
Отвечая на общий вопрос
Для неоднородных периодов времени, таких как месяцы, может потребоваться определенное количество догадок. Во время Noda мы выполняем некоторые вычисления, добираясь до «разумного предположения», (скажем) разделив длительность в тактах на «среднее количество тактов в месяц», затем используя остальную часть кода, чтобы попробовать это предположение и посмотреть, было ли оно правильным или нет. Если это не так, мы корректируем предположение и повторяем попытку.
Теперь возможно, что эти предположения будут постепенно становиться менее точными с увеличением промежутков времени — потому что «среднее количество тиков в месяц» может быть неточным. Тем не менее, я подозреваю, что это должно было бы произойти в течение очень большого периода времени, чтобы иметь существенное значение. Более вероятно, что предположение будет отклоняться на один или два из-за граничных условий в месяцах (например, просто неправильная сторона длинного месяца) — и это может произойти где угодно.
Также обратите внимание, что некоторые календарные системы более поддаются оптимизации, чем другие, и на некоторые из них вполне могут повлиять рассматриваемые даты. Например, если у вас есть разделенный юлианский / григорианский календарь с точкой отсечения, я легко могу представить, что для определения периодов между двумя датами, которые пересекают отсечение, требуется больше времени, чем периоды, которые полностью лежат на одной или другой стороне.
В принципе, системы календаря сложны — лучше ничего не предполагать о том, что «это должно быть просто вопросом XYZ …», поскольку это почти обязательно будет неправильно 🙂
Отвечая на конкретный вопрос
Да, ваш второй подход звучит так, как будто он действительно должен быть намного, намного быстрее, чем первый, в течение длительных периодов времени — и любая разница в скорости вычислений для длительных и коротких периодов времени вряд ли вызовет такую большую разницу, даже если она существует; Я сомневаюсь, что вы сможете это увидеть, хотя этоконечно, все же стоит протестировать.
Ответ №3:
Это не имеет никакого значения для всех текущих языков программирования, сред выполнения / платформ и движков баз данных (независимо от того, что подходит.)