diff --git a/Ical.Net.Benchmarks/ApplicationWorkflows.cs b/Ical.Net.Benchmarks/ApplicationWorkflows.cs index 92aa8b29e..3c068ea1f 100644 --- a/Ical.Net.Benchmarks/ApplicationWorkflows.cs +++ b/Ical.Net.Benchmarks/ApplicationWorkflows.cs @@ -5,6 +5,7 @@ using BenchmarkDotNet.Attributes; using Ical.Net.DataTypes; +using NodaTime; using System; using System.Collections.Generic; using System.IO; @@ -14,8 +15,13 @@ namespace Ical.Net.Benchmarks; public class ApplicationWorkflows { - private static readonly CalDateTime _searchStart = CalDateTime.Now.AddDays(-365); - private static readonly CalDateTime _searchEnd = CalDateTime.Now; + private static DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"]; + + private static readonly Instant _searchEnd = SystemClock.Instance.GetCurrentInstant(); + private static readonly ZonedDateTime _searchStart = _searchEnd + .Minus(NodaTime.Duration.FromDays(365)) + .InZone(tz); + private static readonly List _manyCalendars = GetIcalStrings(); private static List GetIcalStrings() @@ -38,7 +44,7 @@ public List SingleThreaded() return _manyCalendars .SelectMany(Calendar.Load) .SelectMany(c => c.Events) - .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Period.StartTime < _searchEnd)) + .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Start.ToInstant() < _searchEnd)) .ToList(); } @@ -49,7 +55,7 @@ public List ParallelUponDeserialize() .AsParallel() .SelectMany(Calendar.Load) .SelectMany(c => c.Events) - .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Period.StartTime < _searchEnd)) + .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Start.ToInstant() < _searchEnd)) .ToList(); } @@ -60,7 +66,7 @@ public List ParallelUponGetOccurrences() .SelectMany(Calendar.Load) .SelectMany(c => c.Events) .AsParallel() - .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Period.StartTime < _searchEnd)) + .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Start.ToInstant() < _searchEnd)) .ToList(); } @@ -72,7 +78,7 @@ public List ParallelDeserializeSequentialGatherEventsParallelGetOccu .SelectMany(Calendar.Load) .AsSequential() .SelectMany(c => c.Events) - .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Period.StartTime < _searchEnd)) + .SelectMany(e => e.GetOccurrences(_searchStart).TakeWhile(p => p.Start.ToInstant() < _searchEnd)) .ToList(); } } diff --git a/Ical.Net.Benchmarks/OccurencePerfTests.cs b/Ical.Net.Benchmarks/OccurencePerfTests.cs index a17ab58ce..ce38a0c89 100644 --- a/Ical.Net.Benchmarks/OccurencePerfTests.cs +++ b/Ical.Net.Benchmarks/OccurencePerfTests.cs @@ -6,6 +6,7 @@ using BenchmarkDotNet.Attributes; using Ical.Net.CalendarComponents; using Ical.Net.DataTypes; +using NodaTime; using System; using System.Collections.Generic; using System.Linq; @@ -17,6 +18,8 @@ public class OccurencePerfTests private Calendar _calendarFourEvents = null!; private Calendar _calendarWithRecurrences = null!; + private static DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"]; + [GlobalSetup] public void Setup() { @@ -27,35 +30,69 @@ public void Setup() [Benchmark] public void GetOccurrences() { - _ = _calendarWithRecurrences.GetOccurrences().ToList(); + _ = _calendarWithRecurrences.GetOccurrences(tz).ToList(); } [Benchmark] public void MultipleEventsWithUntilOccurrencesSearchingByWholeCalendar() { - var searchStart = _calendarFourEvents.Events.First().DtStart!.AddYears(-1); - var searchEnd = _calendarFourEvents.Events.Last().DtStart!.AddYears(1); - _ = _calendarFourEvents.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .InZoneLeniently(tz) + .ToInstant(); + + _ = _calendarFourEvents.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd); } [Benchmark] public void MultipleEventsWithUntilOccurrences() { - var searchStart = _calendarFourEvents.Events.First().DtStart!.AddYears(-1); - var searchEnd = _calendarFourEvents.Events.Last().DtStart!.AddYears(1); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .InZoneLeniently(tz) + .ToInstant(); + _ = _calendarFourEvents.Events - .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd)) + .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd)) .ToList(); } [Benchmark] public void MultipleEventsWithUntilOccurrencesEventsAsParallel() { - var searchStart = _calendarFourEvents.Events.First().DtStart!.AddYears(-1); - var searchEnd = _calendarFourEvents.Events.Last().DtStart!.AddYears(1).AddDays(10); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .PlusDays(10) + .InZoneLeniently(tz) + .ToInstant(); + _ = _calendarFourEvents.Events .AsParallel() - .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd)) + .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd)) .ToList(); } @@ -89,7 +126,7 @@ private static Calendar GetFourCalendarEventsWithUntilRule() { var rrule = new RecurrencePattern(FrequencyType.Daily, 1) { - Until = new CalDateTime(startTime.AddDays(10)), + Until = startTime.AddDays(10), }; var e = new CalendarEvent @@ -98,7 +135,7 @@ private static Calendar GetFourCalendarEventsWithUntilRule() End = startTime.AddMinutes(10).ToTimeZone(tzid), RecurrenceRules = new List { rrule }, }; - startTime = startTime.Add(Duration.FromTimeSpanExact(interval)); + startTime = startTime.Add(DataTypes.Duration.FromTimeSpanExact(interval)); return e; }); @@ -111,19 +148,41 @@ private static Calendar GetFourCalendarEventsWithUntilRule() public void MultipleEventsWithCountOccurrencesSearchingByWholeCalendar() { var calendar = GetFourCalendarEventsWithCountRule(); - var searchStart = calendar.Events.First().DtStart!.AddYears(-1); - var searchEnd = calendar.Events.Last().DtStart!.AddYears(1); - _ = calendar.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .InZoneLeniently(tz) + .ToInstant(); + + _ = calendar.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd); } [Benchmark] public void MultipleEventsWithCountOccurrences() { var calendar = GetFourCalendarEventsWithCountRule(); - var searchStart = calendar.Events.First().DtStart!.AddYears(-1); - var searchEnd = calendar.Events.Last().DtStart!.AddYears(1); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .InZoneLeniently(tz) + .ToInstant(); + _ = calendar.Events - .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd)) + .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd)) .ToList(); } @@ -131,11 +190,23 @@ public void MultipleEventsWithCountOccurrences() public void MultipleEventsWithCountOccurrencesEventsAsParallel() { var calendar = GetFourCalendarEventsWithCountRule(); - var searchStart = calendar.Events.First().DtStart!.AddYears(-1); - var searchEnd = calendar.Events.Last().DtStart!.AddYears(1).AddDays(10); + var searchStart = _calendarFourEvents.Events.First().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(-1) + .InZoneLeniently(tz); + + var searchEnd = _calendarFourEvents.Events.Last().DtStart! + .ToZonedDateTime(tz) + .LocalDateTime + .PlusYears(1) + .PlusDays(10) + .InZoneLeniently(tz) + .ToInstant(); + _ = calendar.Events .AsParallel() - .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Period.StartTime < searchEnd)) + .SelectMany(e => e.GetOccurrences(searchStart).TakeWhile(p => p.Start.ToInstant() < searchEnd)) .ToList(); } diff --git a/Ical.Net.Benchmarks/ThroughputTests.cs b/Ical.Net.Benchmarks/ThroughputTests.cs index 323676e4e..b3160e408 100644 --- a/Ical.Net.Benchmarks/ThroughputTests.cs +++ b/Ical.Net.Benchmarks/ThroughputTests.cs @@ -6,11 +6,14 @@ using BenchmarkDotNet.Attributes; using System.Linq; using Ical.Net.DataTypes; +using NodaTime; namespace Ical.Net.Benchmarks; public class ThroughputTests { + private static DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"]; + [Benchmark] public void DeserializeAndComputeUntilOccurrences() { @@ -68,9 +71,12 @@ rsion 08.00.0681.000"">\n\n\n\n