sstephenson/sprockets — pull request #577 by josh (2014-05-19 23:10:09+00:00)
Title: Experiment: Parallelize building assets for bundle

I'd say for anyone using CoffeeScript, the majority of the builds are just stuck parked and waiting for the subshell to node.js finish compiling the `.coffee` file. Plus Sprockets does all sort of other file reads and stats. Its heavily IO bound.

Theres a number of ways to approach this type of problem. Here I'm looking at a way parallelize builds for bundled assets.

You can't simply just build **all** of an assets subdependencies in parallel since building the dependencies yields it own subdependencies. However, we can parallelize each level pretty easily.

Say you have `app.js`

```
//= require a
//= require b
//= require c
```

Then say `a.js`

```
//= require a1
//= require a2
//= require a3
```

When we start at `app.js` we get three dependencies. We can kick off subprocesses to start working on all three. Then we block on the first, `a.js` finishing. Then we look at it three dependencies, push them into our work queue and kill off more subprocesses. Then block on the next `b.js`.

None of these spawn off nested subtrees of there own threads. It doesn't get that crazy.

Still, I feel like there needs to be some queuing. At most .com spawns up 70 threads, since we have a main index of hard coded requires. I don't know how good Ruby's thread scheduler is, having 70 threads going probably adds more context switching for the worse.

On a cold build for github.com, Sprockets 3 `master` builds it in 10 seconds. Compared to this branch at about 3 seconds.

```
user	system	total	realtime
0.150000 0.130000 9.690000 ( 9.701224)
0.200000 0.160000 15.160000 ( 3.128563)
```

/cc @dgraham @mislav