Skip to content

Commit a98968e

Browse files
committed
Parallelize initial rust extraction
This is quite slow and embarassingly parallel, even in python. This speeds up the initial bootstrap build by about 5-10s.
1 parent 46a2558 commit a98968e

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

src/bootstrap/bootstrap.py

+68-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import tempfile
1414

1515
from time import time
16+
from multiprocessing import Pool, cpu_count
1617

1718
try:
1819
import lzma
@@ -392,6 +393,48 @@ def channel(self):
392393
return self.version + "-" + self.date
393394

394395

396+
class DownloadInfo:
397+
"""A helper class that can be pickled into a parallel subprocess"""
398+
399+
def __init__(
400+
self,
401+
base_download_url,
402+
download_path,
403+
bin_root,
404+
tarball_path,
405+
tarball_suffix,
406+
checksums_sha256,
407+
pattern,
408+
verbose,
409+
):
410+
self.base_download_url = base_download_url
411+
self.download_path = download_path
412+
self.bin_root = bin_root
413+
self.tarball_path = tarball_path
414+
self.tarball_suffix = tarball_suffix
415+
self.checksums_sha256 = checksums_sha256
416+
self.pattern = pattern
417+
self.verbose = verbose
418+
419+
def download_component(download_info):
420+
if not os.path.exists(download_info.tarball_path):
421+
get(
422+
download_info.base_download_url,
423+
download_info.download_path,
424+
download_info.tarball_path,
425+
download_info.checksums_sha256,
426+
verbose=download_info.verbose,
427+
)
428+
429+
def unpack_component(download_info):
430+
unpack(
431+
download_info.tarball_path,
432+
download_info.tarball_suffix,
433+
download_info.bin_root,
434+
match=download_info.pattern,
435+
verbose=download_info.verbose,
436+
)
437+
395438
class RustBuild(object):
396439
"""Provide all the methods required to build Rust"""
397440
def __init__(self):
@@ -446,8 +489,31 @@ def download_toolchain(self):
446489
("cargo-{}".format(toolchain_suffix), "cargo"),
447490
]
448491

449-
for filename, pattern in tarballs_to_download:
450-
self._download_component_helper(filename, pattern, tarball_suffix, rustc_cache)
492+
tarballs_download_info = [
493+
DownloadInfo(
494+
base_download_url=self.download_url,
495+
download_path="dist/{}/{}".format(self.stage0_compiler.date, filename),
496+
bin_root=self.bin_root(),
497+
tarball_path=os.path.join(rustc_cache, filename),
498+
tarball_suffix=tarball_suffix,
499+
checksums_sha256=self.checksums_sha256,
500+
pattern=pattern,
501+
verbose=self.verbose,
502+
)
503+
for filename, pattern in tarballs_to_download
504+
]
505+
506+
# Download the components serially to show the progress bars properly.
507+
for download_info in tarballs_download_info:
508+
download_component(download_info)
509+
510+
# Unpack the tarballs in parallle.
511+
# In Python 2.7, Pool cannot be used as a context manager.
512+
p = Pool(min(len(tarballs_download_info), cpu_count()))
513+
try:
514+
p.map(unpack_component, tarballs_download_info)
515+
finally:
516+
p.close()
451517

452518
if self.should_fix_bins_and_dylibs():
453519
self.fix_bin_or_dylib("{}/bin/cargo".format(bin_root))

0 commit comments

Comments
 (0)