mangstadt / biweekly

biweekly is an iCalendar library written in Java.
BSD 2-Clause "Simplified" License
323 stars 44 forks source link

Performance issue parsing iCalendar files with VTIMEZONE components #37

Closed mangstadt closed 8 years ago

mangstadt commented 8 years ago

spring.ics.txt

Parsing the above iCalendar file takes a very long time. Removing the VTIMEZONE component from the file speeds the parse time up significantly, so the issue appears to be with how biweekly is handling this component.

The bottleneck seems to be that, in order to convert the necessary date/time property values to the given timezone, it wants to calculate the daylight savings time switch-over dates for every year since 1600 (this is the start date defined in the VTIMEZONE component). And it repeats this process from scratch for every date/time property that's using the timezone.

The code in question is located in the ICalTimeZone.getObservanceBoundary(int, int, int, int, int, int) method. In two places, a RecurrenceIterator object is created and iterated over until the right date is found. Caching the values that this iterator generates may help with performance. It is unclear whether the RecurrenceIterator.advanceTo() method will help, as this may cause the iterator to skip over the value that it's looking for (in at least one case).

Workaround:

A workaround is to use Olson timezone IDs. This forces biweekly to use Java's integrated timezone definitions, which greatly speeds up the parsing process. To do this, simply prepend every TZID parameter value with a "/", like so:

DTSTART;TZID="/Europe/Istanbul":20160628T110000

If you have no control over how the .ics files are created, this could be accomplished with some simple "find and replace" code on the .ics file contents.

mangstadt commented 8 years ago

Significantly improved performance in 2dc0db38de11b60ca7e426c3d6c8e72829231e79.