-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make cron validate x100 faster #299
Make cron validate x100 faster #299
Conversation
…function this commit is a preparation of the introduction of a cache mechanism to speed up the execution of cron-validate. Although the commit looks irrelevant if considered in isolation, it greatly simplify the analysis of the next commit. I also removed unused imports from index.ts Signed-off-by: albertodiazdorado <[email protected]>
In the previous source code version we would load the built-in presets on every invocation of 'cron' (via 'validateOptions'). This means that we do a lot of repeated work on consecutive invocations of 'cron'. With the new design we load the presets just once when we load the module 'options.ts', via the new function 'loadPresets()'. In order to avoid circular dependencies, I modified 'presets.ts' to export just vanilla JavaScript objects. Signed-off-by: albertodiazdorado <[email protected]>
cron-validated was very slow when called in a loop. The reason is that we repeated all these operations in every call: 1. Merge the preset and the overrides into a so-called 'unvalidatedConfig' 2. Dynamically generate a yup validation schema from the preset and the override 3. Validate the 'unvalidatedConfig' using the dynamically generated schema Step 2 is particularly slow, but steps 1 and 3 aren't particularly fast either. Luckily for us, all these 3 steps are perfectly cacheable. This Pull Request introduces a so-called 'optionsCache' to avoid repeating the 3 steps if we already executed them in the past (which happens all the time in a loop). The cache is a map from 'cache keys' to 'validated options'. The cache key is the concatenarion of 'presetId' and a stringified 'override' object. If two function calls produce the same cache key, it invariably means that the user wants to use the same 'Options' in both function calls. This is how the cache produces a performance improvement of about x100 for consecutive calls. Note that the construction of the cache key is not optimized. If the user uses 'cron-validate' two consecutive times with identical 'override' objects, but swaps the order of the override object fields, then they will not benefit from caching. This can be fixed by using deterministic stringification, but I do not consider it necessary. Signed-off-by: albertodiazdorado <[email protected]>
Hey, first of all, thanks for the work. |
Thanks @Airfooox ! I would be willing to re-implement this feature in a different way that you like better, so don't hesitate to offload some work on me :) |
hey there! I made some changes in the next branch due to some issues posted in this repo. Could you change your pr so you push to the next branch? Thanks! |
On it @Airfooox |
This Pull Request addresses #81
Foreword
I believe that this Pull Request contains the right ideas to make
cron-validate
perform reasonably fast. However, I am not sure if my implementation aligns with your designs idea @AirfoooxThus, please let me know if you disagree with the implementation and we can try to find a better means to integrate the performance improvements into the library.
Description
This Pull Request introduces two small optimizations that makes
cron-validate
x100 faster when called in a loop. The changes are:options
") instead of when callingvalidateOptions
. Since the build-in presents do not change, we can load them just once instead of loading them every time that we usecron()
cron()
with the same settings multiple time (defined by preset/presetId and overrides), then we would spend quite a lot of time creating and validating anOptions
object. The creation & validation of this object makes the library about x100 faster when called in a loop.Benchmarking
I used this script for benchmarking, using some cron expressions akin to the ones I have been dealing with in production:
To execute the benchmark, do:
git checkout $branch npm run build node profile.mjs
On my machine, these are the results for
master
:These are the results for
make-cron-validate-x100-faster
: