#c# #performance #datetime #decimal
#c# #Производительность #datetime #десятичная
Вопрос:
У меня есть DateTime
и мне нужно получить дни и часы в десятичном формате. Например, для new DateTime(2009, 6, 19, 18, 0, 0);
мне нужны дни как 19.75
. Day (TimeOfDay.TotalHours / 24)
кажется, работает, но есть ли прямое или лучшее преобразование? Скорость важна для этого вычисления, учитывая, что я также использую даты с высоким разрешением.
Комментарии:
1. Вы пробовали использовать промежуток времени ?
2. Я думаю, что new timespan().totaldays работает
Ответ №1:
Дано…
DateTime time = new DateTime(2009, 6, 19, 18, 0, 0);
…что у вас есть…
decimal totalDays1 = (decimal) (time.Day time.TimeOfDay.TotalHours / 24);// 19.75M
…уже довольно сжато, поэтому я не знаю, насколько вы хотите или ожидаете улучшить это. Вы могли бы использовать TimeSpan.TotalDays
свойство, но для его настройки требуется немного больше работы…
DateTime lastDayOfPreviousMonth = new DateTime(time.Year, time.Month, 1).AddDays(-1);
decimal totalDays2 = (decimal) (time - lastDayOfPreviousMonth).TotalDays;// 19.75M
Я использовал BenchmarkDotNet для сравнения четырех различных методов…
using System;
using BenchmarkDotNet.Attributes;
public static class Program
{
static void Main(string[] args)
{
BenchmarkDotNet.Running.BenchmarkRunner.Run<CalculateTotalDaysBenchmarks>();
}
}
[ClrJob()]
[CoreJob()]
public class CalculateTotalDaysBenchmarks
{
private static readonly DateTime TestTime = new DateTime(2009, 6, 19, 18, 0, 0);
[Benchmark(Baseline = true)]
public decimal Method1_DayPlusTotalHoursDivided_CastResult()
{
return (decimal) (TestTime.Day TestTime.TimeOfDay.TotalHours / 24);
}
[Benchmark()]
public decimal Method1_DayPlusTotalHoursDivided_CastTotalHours()
{
return TestTime.Day (decimal) TestTime.TimeOfDay.TotalHours / 24;
}
[Benchmark()]
public decimal Method2_DayPlusTicksDivided()
{
return TestTime.Day (decimal) TestTime.TimeOfDay.Ticks / TimeSpan.TicksPerDay;
}
[Benchmark()]
public decimal Method3_SubtractLastDayOfPreviousMonth()
{
DateTime lastDayOfPreviousMonth = new DateTime(TestTime.Year, TestTime.Month, 1).AddDays(-1);
return (decimal) (TestTime - lastDayOfPreviousMonth).TotalDays;
}
[Benchmark()]
public decimal Method4_NewTimeSpan()
{
return (decimal) new TimeSpan(TestTime.Day, TestTime.Hour, TestTime.Minute, TestTime.Second, TestTime.Millisecond).TotalDays;
}
}
… и получил эти результаты…
// * Summary *
BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.379 (1809/October2018Update/Redstone5)
Intel Core i7 CPU 860 2.80GHz (Nehalem), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.505
[Host] : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT
Clr : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3362.0
Core : .NET Core 2.1.9 (CoreCLR 4.6.27414.06, CoreFX 4.6.27415.01), 64bit RyuJIT
| Method | Runtime | Mean | Error | StdDev | Ratio | RatioSD |
|------------------------------------------------ |-------- |---------:|----------:|----------:|------:|--------:|
| Method1_DayPlusTotalHoursDivided_CastResult | Clr | 118.2 ns | 1.2644 ns | 1.1827 ns | 1.00 | 0.00 |
| Method1_DayPlusTotalHoursDivided_CastTotalHours | Clr | 263.9 ns | 0.7289 ns | 0.6462 ns | 2.23 | 0.02 |
| Method2_DayPlusTicksDivided | Clr | 194.1 ns | 0.8827 ns | 0.8256 ns | 1.64 | 0.02 |
| Method3_SubtractLastDayOfPreviousMonth | Clr | 138.9 ns | 0.4757 ns | 0.3714 ns | 1.17 | 0.01 |
| Method4_NewTimeSpan | Clr | 134.7 ns | 0.8376 ns | 0.7835 ns | 1.14 | 0.01 |
| | | | | | | |
| Method1_DayPlusTotalHoursDivided_CastResult | Core | 113.3 ns | 0.1982 ns | 0.1655 ns | 1.00 | 0.00 |
| Method1_DayPlusTotalHoursDivided_CastTotalHours | Core | 261.3 ns | 2.9683 ns | 2.6313 ns | 2.31 | 0.02 |
| Method2_DayPlusTicksDivided | Core | 197.9 ns | 4.4254 ns | 5.2681 ns | 1.74 | 0.04 |
| Method3_SubtractLastDayOfPreviousMonth | Core | 131.1 ns | 0.8406 ns | 0.7863 ns | 1.16 | 0.01 |
| Method4_NewTimeSpan | Core | 132.1 ns | 1.1211 ns | 1.0486 ns | 1.16 | 0.01 |
То, с чего вы начали, заметно быстрее, чем другие методы.
Комментарии:
1. Не уверен, что одно лучше другого, когда дело доходит до скорости …. новый временной интервал (cd.День, cd.Час, cd.Минута, cd.Секунда, cd.Миллисекунда). Общее количество дней;
2. Ах, это тоже работает, хотя и сокращает любое время до миллисекунды, если это имеет значение для вас. Скорость — это то, к чему вы стремитесь? Ясность? Меньше символов?
3. Скорость важна для этого вычисления, учтите, что я также использую даты в высоком разрешении.
4. Я добавил тестовый код и результаты к своему ответу.