brick / date-time

Date and time library for PHP
MIT License
337 stars 30 forks source link

[performance] Optimize LocalDate::plusDays(1) calls. #79

Closed gnutix closed 1 year ago

gnutix commented 1 year ago

Fixes #78.

Local PHP script-based benchmark shows that for 10'000'000 iterations of LocalDate::plusDays(1) (from 2023-09-15 to 29402-10-11) takes an average of 25 seconds without this patch, and an average of 5 seconds with it. Adding the patch does not change the results if the input argument of plusDays() is something else than 1 (or only a non-noticeable amount).

Benchmark script ```php start(); for ($i = 0; $i < 10_000_000; ++$i) { $date = $date->plusDays(2); if ($i === 0 || $i === 9_999_999) { dump((string) $date); } } $stopwatch->stop(); dd((string) $stopwatch->getElapsedTime()); ```

I understand this is quite a specific patch, mostly related to our own use case in our code base, but I still think it might benefit users of this library, because looping from day to day seems like quite a common use case (it's done even within the library, in LocalDateRange::getIterator() and LocalDate::plusWeekdays()).

We thought of adding a -1 use case too, but it's way more complicated to implement, and I'd guess it's not as useful/impactful.

Credit goes to @BastienClement.

BenMorel commented 1 year ago

Looks good! I agree this is a very common operation, and deserves the x5 performance boost this extra code brings.

gnutix commented 1 year ago

(Final Edit): OK, there's no more performance improvement I can think of for now. :sweat_smile:

Could you please create a new minor release once this PR is merged ? :pray:

BenMorel commented 1 year ago

@gnutix Released as 0.5.2! Thanks for your contribution.

gnutix commented 1 year ago

Thanks @BenMorel! Would you mind adding @BastienClement in the release note as a contributor (if you can edit it) ? He did most of the thinking behind those 3 PRs. :)

BenMorel commented 1 year ago

@gnutix No problem, done!

https://github.com/brick/date-time/releases/tag/0.5.2