servo: Merge #7632 - Speedup mach startup (from aidanhs:aphs-speedup-mach-startup); r=metajack
authorAidan Hobson Sayers <aidanhs@cantab.net>
Wed, 16 Sep 2015 14:34:17 -0600
changeset 383803 f85e0eba385cbdd40a2fbc649e57d967d882e437
parent 383802 267a92e5a6056495ba1cc39890a923bd1ea8efce
child 383804 d745af4a8353bb4111ae90a945b1b54a964877a0
push id7198
push userjlorenzo@mozilla.com
push dateTue, 18 Apr 2017 12:07:49 +0000
treeherdermozilla-beta@d57aa49c3948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmetajack
servo: Merge #7632 - Speedup mach startup (from aidanhs:aphs-speedup-mach-startup); r=metajack ...by using a 'marker file' to indicate whether we actually need to run pip. Also a minor tweak for clarity. Before (consistently): ``` $ time ./mach >/dev/null real 0m0.666s user 0m0.477s sys 0m0.190s ``` After: ``` $ time ./mach >/dev/null # first run real 0m0.665s user 0m0.501s sys 0m0.166s $ time ./mach >/dev/null real 0m0.121s user 0m0.083s sys 0m0.039s ``` Source-Repo: https://github.com/servo/servo Source-Revision: b511004a616862394318381d7ef5ac3c59c7babe
servo/mach
servo/python/mach_bootstrap.py
--- a/servo/mach
+++ b/servo/mach
@@ -11,15 +11,15 @@
 
 from __future__ import print_function, unicode_literals
 
 import os
 import sys
 
 def main(args):
     topdir = os.path.dirname(sys.argv[0])
-    sys.path[0:0] = [os.path.join(topdir, "python")]
+    sys.path.insert(0, os.path.join(topdir, "python"))
     import mach_bootstrap
     mach = mach_bootstrap.bootstrap(topdir)
     sys.exit(mach.run(sys.argv[1:]))
 
 if __name__ == '__main__':
     main(sys.argv)
--- a/servo/python/mach_bootstrap.py
+++ b/servo/python/mach_bootstrap.py
@@ -91,22 +91,31 @@ def _activate_virtualenv(topdir):
 
     # TODO: Right now, we iteratively install all the requirements by invoking
     # `pip install` each time. If it were the case that there were conflicting
     # requirements, we wouldn't know about them. Once
     # https://github.com/pypa/pip/issues/988 is addressed, then we can just
     # chain each of the requirements files into the same `pip install` call
     # and it will check for conflicts.
     requirements_paths = [
-        os.path.join(topdir, "python", "requirements.txt"),
-        os.path.join(topdir, "tests", "wpt", "harness", "requirements.txt"),
-        os.path.join(topdir, "tests", "wpt", "harness", "requirements_servo.txt"),
+        os.path.join("python", "requirements.txt"),
+        os.path.join("tests", "wpt", "harness", "requirements.txt"),
+        os.path.join("tests", "wpt", "harness", "requirements_servo.txt"),
     ]
-    for path in requirements_paths:
-        subprocess.check_call(["pip", "install", "-q", "-r", path])
+    for req_rel_path in requirements_paths:
+        req_path = os.path.join(topdir, req_rel_path)
+        marker_file = req_rel_path.replace(os.path.sep, '-')
+        marker_path = os.path.join(virtualenv_path, marker_file)
+        try:
+            if os.path.getmtime(req_path) + 10 < os.path.getmtime(marker_path):
+                continue
+        except OSError:
+            open(marker_path, 'w').close()
+        subprocess.check_call(["pip", "install", "-q", "-r", req_path])
+        os.utime(marker_path, None)
 
 
 def bootstrap(topdir):
     topdir = os.path.abspath(topdir)
 
     # Ensure we are running Python 2.7+. We put this check here so we generate a
     # user-friendly error message rather than a cryptic stack trace on module
     # import.