Incremental builds are slow

I posted this in https://github.com/purescript/purescript/issues/3557:

I have a test project that implements a React based calculator web app. It has two .purs source files and a number of dependency for a total of 456 folders in the output/ directory after compilation completes. I did some tests and incremental builds take long that I would expect them to. Here’s the data:

full build: 10.47s
rebuild (no changes): 2.93s
rebuild (trivial change to src/Calculator.purs): 3.18s

I assume that rebuilds require parsing and traversing dependencies to make sure that everything still makes sense in Calculator.purs after my change. If that is indeed the case, is there anyway that that data can be cached between runs? I tried pulp --watch build and it also takes about 3 seconds after making a change to Calculator.purs.

@hdgarrood suggested a couple of issues that might help with this:

As someone who has almost no experience with the purescript code base, the first two seem more feasible in the short term.

I’m curious how people feel about adding a “watch” mode to purs compile or it would make more sense for purs compile to do a better job of handling incremental builds and let pulp handle the watching. If purs was responsible for watching then we probably wouldn’t need to worry about computing hashes of all of the files each time.

FWIW a lot of people use purs ide with their editor, which supports compilation of single modules. This combined with a bundler watching output (such as through webpack or parcel) gives you near instant rebuilds, at the cost of occasional inconsistency. purs ide “fast builds” only compile the module you’re working on, and so you can occasionally get a run time error if you don’t do a full build. I usually work with purs ide in vscode, and then if anything changes a module import/export I hit cmd + shift + b to do a full build. This workflow is very responsive.

As far as incremental speed for full builds, purescript-cst will offer about a 6-7x improvement in parsing speed, which is a pretty decent speed boost! It’s ready to start integrating, so hopefully we can see it pay-off soon, but otherwise we will have to resort to better caching.

I doubt we will ever have a “watch” mode that’s different than what purs ide offers, as I’d consider that the spiritual equivalent.

4 Likes

Thanks for sharing your setup.

I’m using the same plugin. I think my mistake was trying to using pulp bundle at the same time. I’ll try using a separate tool for bundling. Watching the plugin’s output it looks like the full rebuilds are only necessary when installing a new dependency. I tried adding a new import for a dependency I already had and the rebuild was fast as well.

When adding new dependencies it would be nice if the plugin automatically triggered a full build. When I first started using PureScript in VSCode I was confused why it didn’t recognize new deps and was confused. I think this is why I started using pulp as well. Since I’m using VSCode I think I’ll investigate how to make it trigger a full rebuild if bower_components changes. The tricky thing about this though, is knowing when bower is actually finished its work.

I’m not sure how pulp --watch build works, but it seems like it should be faster if it was using purs ide. Maybe there’s some bad interaction going on between the VSCode plugin and using pulp at the same time.

I’d prefer the “watch” functionality to be outside of the purs compile. I like that that command has a single clear responsibility. I think “Use content hashes…” and “Building against pre-compiled dependencies” are the answers here, at least until there are cases of PS projects which are in fact so big that even those don’t resolve the compile time issue.

It just watches your src tree for changes and calls purs build. You might also look at pscid.

It sounds like this is actually a solved problem. The actually problem I experienced was that there are many possible ways to build things and all of the ones I tried until now had slow incremental build times.

I’m going investigate pscid because it sounds like it might be fast without requiring a particular editor/plugin setup. It would be nice if there were a couple of boilerplate repos with known fast configurations that people could clone as starting points. Another option might be a tool similar to create-react-app that allows people to easily create a new project with a fast build tool-chain already set up.

1 Like