rlanvin / php-rrule

Lightweight and fast recurring dates library for PHP (RFC 5545)
Other
601 stars 83 forks source link

Performance? #40

Closed reinink closed 6 years ago

reinink commented 6 years ago

Hey there! I just came across this library (https://github.com/rlanvin/php-rrule), and I was hoping to ask you a couple questions about it, if you don't mind. ❤️

To date I've used the https://github.com/simshaun/recurr library on my projects. Did you create your library because you were not happy with this specific implementation? I'm curious if you're able to share how your library is different?

The one issue I ran into when generating RRULEs is performance. Everything works okay if you're only generating a set of dates for a short period of time, but if you generate them for a long period of time it can be a very slow process.

For example, someone may choose to create a recurring date that started 5 years ago and repeats every single week. I may have a calendar that I want to show all the events on for the current month. With the simshaun/recurr library I can scope the results between two dates (the current month), which is great, but really all it does it run the RRULE for the entire time period and then chop off dates outside of the range given. This had led to poor performance, since it takes a bit to generate them all.

Does this library do things any different? How's the performance for large date ranges like this?

Thanks!

rlanvin commented 6 years ago

Hi!

Did you create your library because you were not happy with this specific implementation? I'm curious if you're able to share how your library is different?

Indeed that is the reason I created it. Happy to discuss this in more details, but first a little disclaimer: I created this lib a couple of years ago, and I haven't checked the status of the other libraries recently, so my comments here might be outdated.

I remember trying the lib you mentioned. It was slow and completely over-engineered. Quite frankly I absolutely hated the very verbose interface with way too much bloat. Case in point: it requires doctrine/collections - this is a major code smell for me, I like to keep things simple.

After looking a various Ruby implementations (which suffered the same problem from PHP ones), I discovered the Python version which was built around a generator and had everything I needed, so I just ported it and adapted it for PHP. All the credit for the algorithm go to them, they did an amazing job.

Does this library do things any different?

No not really, because actually this is the correct way to do it, as surprising as it sounds. Recurrence rules can be very tricky and the only way to calculate the occurrences 5 years from the starting date is to actually compute 5 years worth of occurrences.

How's the performance for large date ranges like this?

Depends what you call "poor performance", how long does it take at the moment? Weekly rules should be fast. There is only 52 occurrences per year, so roughly 260 iterations over 5 years - that's very quick if the lib is coded well, and not a large date range by any mean. I did a quick test, my lib handles that in about 20ms on my development virtual machine, which is a perfectly acceptable performance for me. Code is below if you want to test with your own rule.

$start = microtime(true);
$iter = 10; // trying 10 times to get an average
for ( $i = 0; $i < $iter; $i++ ) {
    $rule = new RRule\RRule([
        'FREQ' => 'WEEKLY',
        'INTERVAL' => 1,
        'BYDAY' => 'FR',
        'DTSTART'=> '2010-01-01' // over 7 years ago
    ]);

    $rule->getOccurrencesBetween('2017-11-01', '2017-11-30'); // occurrences this month
}
$stop = microtime(true);
echo "Average ".(($stop-$start)/$iter).'s';

Let me know, I'm curious to know how it compares!

reinink commented 6 years ago

Hey thanks! I very much appreciate the detailed answer. That's quite helpful.

From my initial testing this library appears to be, at a minimum, 2.5x faster, and sometimes as high as 5x faster. That's pretty significant.

I'm going to give this library a try on a new project an see how it goes! 👍

rlanvin commented 6 years ago

From my initial testing this library appears to be, at a minimum, 2.5x faster, and sometimes as high as 5x faster. That's pretty significant.

Wow! That's nice to hear. I never really took the time to compare performances with other libs, maybe I'll run benchmarks at some point. :)

I'm going to give this library a try on a new project an see how it goes!

Great! Feel free to open more issues if you have questions. Suggestions and pull requests are always welcome.

iamroi commented 6 years ago

You sir, are a legend @rlanvin! Add me to your fan library. ❤️

rlanvin commented 6 years ago

@mrajabtech Well thank you!