What I would do to really squeeze the rest out in pure ruby (bear in mind I’ve been away about a decade so there _might be_ new bits but nothing meaningful as far as I know):
Use a cheaper to parse index format (the gists I wrote years ago cover this: https://gist.github.com/raggi/4957402)
Use threads for the initial archive downloads (this is just io, and you want to reuse some caches like the index)
Use a few forks for the unpacking and post install steps (because these have unpredictable concurrency behaviors)