PSA: Faster builds with YJIT

Dear fellow Jekyllers!

I just went on a deep dive into trying to reduce the rendering time of my site as it just crossed the 20 minute mark.

First, I tried to Parallelize the main Jekyll rendering loop… but the fork operation ended up being so slow that this only speeds things up if you have ≥4 processors… which GitHub runners do not.

To cut a long story short, I eventually discovered that Ruby 3.1 has an experimental new feature called YJIT.

Built by Shopify themselves and specifically optimized for liquid template rendering, YJIT reduces Jekyll build times anywhere from 15%–40%.

To enable YJIT, simply upgrade to Ruby 3.1 and add this bash line before your build command:

export RUBYOPT="--enable=yjit"

In my case, it reduced my build times by about 25%: from just over 20 min to under 15 min. Not bad for a one liner!

Happy Jekylling everybody!

5 Likes

Wow, thank you a lot for that; my site now builds time of around nearly 10 minutes. And I think it is time to reduce something.

1 Like

Indeed, it speeds up! Thank you.
But what am I doing wrong? :innocent: My build time dropped from 3.7 seconds to 2.8 seconds – nice speedup, %wise. The site has a little over 1200 pages with extensive liquid code. If I jekyll clean beforehand, build time goes up to ≈13 seconds. Hmm…

1 Like

I assume that your ~3 sec build was incremental — when you clean you’re forcing it to build from scratch. For an apples-to-apples comparison, you should clean before each test run.

Also keep in mind the the export command will keep that environment variable set for the rest of your bash session. So, to turn YJIT off, you’ll have to explicitly export RUBYOPT="--disable=yjit" to test without.

Nice!

I think the majority of my build time is coming from an O(n²), naïve k-NN algorithm I use to suggest “other posts you may like” from among the ~2000 pieces on my site.

My next target for decreasing my build time is to speed this algorithm up by precomputing a space-partition structure… but that’s less relevant to the broader Jekyll community, as I don’t think many of you are rolling your own “Related Posts” algorithm (are you?) If there’s interest though, I can tell y’all about that too after I get it working :grin:

1 Like

Indeed, adding a precomputed, BSP-like data structure reduced my build time from 15 min to 2 min :smile:

Congrats! Waiting ⅓ of an hour for every build… Can’t imagine.

1 Like

That’s cool. Looking forward to how you do it. :face_with_monocle: :+1:

Is that a question? If so:
export RUBYOPT="--enable=yjit"
To make it permanent, add to you .zshrc or whatever shell you’re using.

Lol, the Jekyll community has a lot of background support from developers of Shopify. It very funny, but thanks Shopify for the liquid the same as Ruby Jekyll. It help Jekyll community user a lot save time for many solution in futures :rofl:

If by this you meant the reworked k-NN related posts algorithm, you can see the code for that here. The new part of the algorithm is the dataInit function, which builds a static hashmap of posts with a given tag so that I can narrow my k-NN searches down to just the posts that share at least one tag with the query.