-
Notifications
You must be signed in to change notification settings - Fork 1
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
Enable parallel builds #49
Comments
Hi Ecco, Parallel compilation is on my wish list too, but it’s not trivial because of two reasons:
Therefore, while it’s certainly possible to parallelize Nanoc, there would be no significant measurable benefit. One thing that you can do to speed up the compilation of your site is to figure out where the slowness is coming from. Run In particular, the list of filters is interesting to look at; it might be worth using different filters, or optimising slow ones. For example, in one site that I worked on, I swapped out a filter that uses I’ve also attempted to run Nanoc within Docker for Mac for a while, but the slow filesystem lead to a 10x-20x slowdown for Nanoc. (This might not be relevant for you, but I found it worth mentioning.) I’ve also had some success with Bootsnap, which can speed up I’ve spent a lot of effort in optimising Nanoc, and you can see that (I hope) in the fact that repeated builds are significantly faster than clean builds. In some sites that I work on, I can have an editor and a live-reloading browser window open next to each other, and have my changes show up with a sub-second latency. That’s the experience that I aim for for even large Nanoc sites, although that’s not always possible. At this point, however, I believe I might be hitting the limits of what is achievable with Ruby. I’ve experimented with partially reimplementing Nanoc’s core in pre-compiled languages, and that’s certainly a direction that I want to explore further, as I believe there’s a lot of untapped potential. What are your thoughts? |
Hi @ddfreyne ! First of all, thank you very much for such a nice and comprehensive answer! Our use-case might be a bit special: 99% of the time is spent generating PDFs with PDFKit using a custom Those items are all independent one from another, and I'm pretty sure it could be possible to run the filter in parallel. Anyway, I'm going to look at how I could make the filter faster and will keep you posted 😄 |
@Ecco That’s a good point! PDF generation is notoriously slow, and this case might indeed be something that can be parallellized. I’ll need to think a bit more about how to make this work, though. |
I’ve started an experiment to make Nanoc compile items in parallel. You can find it at nanoc/nanoc/pull/1385 — but be warned that this is highly experimental and very much work in progress. |
@Ecco Is there a chance that I can get hold of the source for the web site that you’re talking about? It’d help me in building a properly-parallelized Nanoc. |
Unfortunately, not as is. But I guess I could make a minimum example that reproduces the exact issue we're running into. 99% of that website's sources aren't relevant to this anyway :) |
@Ecco A minimal example would be quite useful! |
Here goes :) |
Look at that:
|
There’s quite a bit more work to do, but the basic stuff is there. I suppose I also need to start thinking about how to report all the recorded durations, since they don’t add up anymore. |
Oh, wow 😮 Color me impressed! I definitely need to take a look at that branch then 😄 As for the way durations are reported, I think the current output is actually great. It's rather clear what each output corresponds to, and they don't really need to add up. |
Unfortunately, for sites that don’t run external processes, the parallel version of Nanoc is 5% to 10% slower. I’ll need to investigate, but it’s probable that the threading/locking/context-switching overhead is causing it. |
Hmm, that's a bummer. Maybe nanoc could use a flag like |
The slowdown is also noticeable when running with a single thread (using the new implementation). I’ve measured lock contention, but it’s small (< 0.5%, don’t have more detailed results). |
While still experimental, I think the PR is in a pretty good shape by now:
The PR introduced quite a bit of code that is not yet thoroughly tested by unit tests and integration tests. I suppose that now is a good time to start working on that. I think you can test out this branch for your own project, but do let me know when you run into unexpected behavior! |
Ruby 3.0 opens up new possibilities here, via Ractors. I’d love to make use of this, though it would mean dropping support for Ruby 2.x. I think it’s too early for this, as Ruby 3.0 is quite new and Ruby 2.6 and 2.7 are still supported. |
I don't know if I'm biased, but I always use a ruby version manager. As a result, installing any version of Ruby is really not a concern for me. I would assume most Ruby devs also do, but I don't know 😄 |
If people are still interested in this, would it make sense to reconsider it now? From https://www.ruby-lang.org/en/downloads/branches/ it looks like 2.7 is end-of-life. (I'd really like to switch to nanoc, but I've got about 2500 images to resize to multiple sizes each, and that seems like a good use of parallelism as long as the GIL/GVL is released when executing an external program.) |
Unfortunately, even in the most recent Ruby version (3.3), ractors are still experimental and not usable in production-like settings. I wrote up some more detail on the lack of parallellism in Nanoc. I am not sure where ractors are headed in the future, but I am keeping my eyes peeled. There would be some benefit to using threads when using external processes (e.g. for resizing images), but I’d much prefer to use ractors, because that’d be far more impactful. |
Builds can take a while. CPUs are getting more and more cores. Let's use them.
Steps to reproduce
nanoc compile
Expected behavior
Just like
make -j N
, it would be great if nanoc could build in parallel and use many cores.Actual behavior
Nanoc processes items sequentially.
The text was updated successfully, but these errors were encountered: