Closed
Bug 922517
Opened 11 years ago
Closed 11 years ago
Parsing test manifests significantly slowed down moz.build reading
Categories
(Firefox Build System :: General, defect)
Firefox Build System
General
Tracking
(Not tracked)
RESOLVED
FIXED
mozilla27
People
(Reporter: gps, Assigned: ziga.seilnacht)
References
Details
Attachments
(3 files, 5 obsolete files)
2.45 KB,
patch
|
Details | Diff | Splinter Review | |
5.68 KB,
patch
|
Details | Diff | Splinter Review | |
1.59 KB,
patch
|
Details | Diff | Splinter Review |
When we moved mochitests to manifests in bug 920223, moz.build traversal slowed down by a few seconds on my machine. We went from ~4s for everything, including backend generation, to ~8s. In this bug, we should profile why manifest loading is slow and we should see if we can make it faster. This bug may get reassigned to mozbase/manifestdestiny. But first, let's collect data to be sure it isn't the build system doing something silly.
Comment 1•11 years ago
|
||
ncalls tottime percall cumtime percall filename:lineno(function) 284865 1.382 0.000 2.106 0.000 posixpath.py:321(normpath) 571983 0.642 0.000 0.897 0.000 posixpath.py:68(join) 742 0.513 0.001 5.230 0.007 emitter.py:235(_process_test_manifest) Removing _process_test_manifest makes normpath and join disappear from the profile, too.
Comment 2•11 years ago
|
||
The number of calls is absurdly high. There might be some O(n*m) badness.
Assignee | ||
Comment 3•11 years ago
|
||
It looks like most of the time is spent normalizing |support-files| paths, here is a profile with _process_test_manifest() split into multiple smaller functions (see the attached patch): ncalls cumtime filename:lineno(function) 1 10.640 build\ConfigStatus.py:28(config_status) 1 10.632 mozbuild\backend\base.py:174(consume) 4469 8.277 mozbuild\frontend\emitter.py:66(emit) 5665 7.516 mozbuild\frontend\emitter.py:89(emit_from_sandbox) 750 6.881 mozbuild\frontend\emitter.py:244(_process_test_manifest) 7903 5.786 mozbuild\frontend\emitter.py:341(_install_extra_support_files) 498993 2.198 mozpack\path.py:31(join) 1 1.967 mozbuild\backend\recursivemake.py:600(consume_finished) 234540 1.965 mozpack\path.py:36(normpath) 235749 1.608 _virtualenv\lib\posixpath.py:321(normpath) The issue occurs when a test manifest has many |support-files| specified in the [DEFAULT] section and lists many tests. manifestparser.read_ini() copies this value to each test's individual config section, and _process_test_manifest() then splits these paths and normalizes them once for each individual test. E.g., for /content/base/test/mochitest.ini, _process_test_manifest() adds 77381 duplicate paths to the |obj.installs| dict. Below is a list of test manifests which cause the most duplicates to be added: 77381 /content/base/test/mochitest.ini 33915 /content/html/content/test/mochitest.ini 15656 /browser/base/content/test/general/browser.ini 12690 /browser/devtools/webconsole/test/browser.ini 11900 /toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini 07504 /browser/devtools/debugger/test/browser.ini 04280 /toolkit/content/tests/chrome/chrome.ini 03264 /dom/tests/mochitest/bugs/mochitest.ini 02912 /netwerk/test/unit/xpcshell.ini 02756 /dom/workers/test/mochitest.ini
Reporter | ||
Comment 4•11 years ago
|
||
Nice investigation! We should avoid the redundant computation for each [test] section, if possible. Since support-files is only supposed to come from the [DEFAULT] section, we should just process it once. We probably also want to verify that support-files isn't defined outside of [DEFAULT].
Comment 5•11 years ago
|
||
Actually, I think it might be useful to support support-files under specific files, so we can avoid copying them when those tests are disabled?
Assignee | ||
Comment 6•11 years ago
|
||
Having |support-files| under specific tests should already be working, changing that is not needed to fix this issue. The attached patch seems to fix the O(tests * support-files) issue for me, most of the time is now spent in ManifestParser._read() path manipulations: ncalls cumtime filename:lineno(function) 1 5.108 ConfigStatus.py:28(config_status) 1 5.100 mozbuild\backend\base.py:174(consume) 4469 2.769 mozbuild\frontend\emitter.py:66(emit) 5665 2.021 mozbuild\frontend\emitter.py:89(emit_from_sandbox) 1 1.919 mozbuild\backend\recursivemake.py:600(consume_finished) 750 1.149 mozbuild\frontend\emitter.py:244(_process_test_manifest) 1204 1.079 mozbuild\backend\configenvironment.py:214(create_makefile) 13715 0.847 _virtualenv\lib\ntpath.py:494(relpath) 5934/1199 0.740 mozbuild\frontend\reader.py:568(read_mozbuild) 5934/1199 0.740 mozbuild\frontend\reader.py:625(_read_mozbuild) 375 0.720 manifestparser\manifestparser.py:359(__init__) 375 0.720 manifestparser\manifestparser.py:420(read) 79175 0.717 _virtualenv\lib\ntpath.py:398(normpath) 378/375 0.704 manifestdestiny\manifestparser\manifestparser.py:371(_read) 27430 0.675 _virtualenv\lib\ntpath.py:486(_abspath_split) 39118 0.447 _virtualenv\lib\ntpath.py:466(abspath) There is still a problem with individual test sections overriding the settings in the [DEFAULT] section; if every test has its own |support-files| specified, then the files listed in [DEFAULT]'s |support-files| wouldn't get installed. To change that, manifestparser.TestManifest would need to expose its |_defaults| dict and its consumers would need to be modified to take the default section into consideration.
Attachment #816225 -
Flags: review?(gps)
Assignee | ||
Comment 7•11 years ago
|
||
Removing a redundant os.path.abspath() call in ManifestParser._read() and bypassing os.path.relpath() call when relative path calculation is trivial shaves another half a second from _process_test_manifest(): ncalls cumtime filename:lineno(function) 1 4.397 ConfigStatus.py:28(config_status) 1 4.389 mozbuild\backend\base.py:174(consume) 4469 2.020 mozbuild\frontend\emitter.py:66(emit) 1 1.970 mozbuild\backend\recursivemake.py:600(consume_finished) 5665 1.274 mozbuild\frontend\emitter.py:89(emit_from_sandbox) 1204 1.109 mozbuild\backend\configenvironment.py:214(create_makefile) 5934/1199 0.738 mozbuild\frontend\reader.py:568(read_mozbuild) 5934/1199 0.738 mozbuild\frontend\reader.py:625(_read_mozbuild) 750 0.603 mozbuild\frontend\emitter.py:244(_process_test_manifest) 1209 0.460 mozbuild\backend\configenvironment.py:238(_get_preprocessor) 5810 0.407 _virtualenv\lib\ntpath.py:494(relpath) 83768 0.405 mozbuild\frontend\sandbox.py:353(__getitem__) 1 0.405 mozbuild\backend\recursivemake.py:414(_fill_root_mk) 31837 0.394 config\Preprocessor.py:219(handleLine) 86829 0.389 mozbuild\frontend\sandbox.py:105(__getitem__) 4468 0.375 mozbuild\backend\recursivemake.py:329(consume_object) 39650 0.363 _virtualenv\lib\ntpath.py:398(normpath) Where should I submit a patch for mozbase, is here OK or do I need to post it to Github?
Attachment #816226 -
Flags: feedback?(gps)
Comment 8•11 years ago
|
||
A patch can be submitted to this bug against the github repo as according to https://wiki.mozilla.org/Auto-tools/Projects/Mozbase
Reporter | ||
Comment 9•11 years ago
|
||
(In reply to :Ms2ger from comment #5) > Actually, I think it might be useful to support support-files under specific > files, so we can avoid copying them when those tests are disabled? I /think/ ATeam wants *every* file in the test archives. I could be wrong.
Assignee | ||
Comment 10•11 years ago
|
||
Here is the manifestparser patch against the github repo's master.
Attachment #816085 -
Attachment is obsolete: true
Attachment #816226 -
Attachment is obsolete: true
Attachment #816226 -
Flags: feedback?(gps)
Attachment #816723 -
Flags: review?(jhammel)
Assignee | ||
Comment 11•11 years ago
|
||
Two of the manifestdestiny's tests are currently failing on Windows due to path separator differences, predating my changes. This fixes them.
Attachment #816725 -
Flags: review?(jhammel)
Reporter | ||
Comment 12•11 years ago
|
||
Comment on attachment 816225 [details] [diff] [review] fix O(tests * support-files) behaviour in _process_test_manifest Review of attachment 816225 [details] [diff] [review]: ----------------------------------------------------------------- Please add an inline comment that the skipping is perf related. Things like this have a tendency to get dropped during refactors unless posterity knows about them.
Attachment #816225 -
Flags: review?(gps) → review+
Comment 13•11 years ago
|
||
(In reply to Gregory Szorc [:gps] from comment #12) > Comment on attachment 816225 [details] [diff] [review] > fix O(tests * support-files) behaviour in _process_test_manifest > > Review of attachment 816225 [details] [diff] [review]: > ----------------------------------------------------------------- > > Please add an inline comment that the skipping is perf related. Things like > this have a tendency to get dropped during refactors unless posterity knows > about them. +1
Comment 14•11 years ago
|
||
Comment on attachment 816723 [details] [diff] [review] optimize ManifestParser._read() path manipulations Review of attachment 816723 [details] [diff] [review]: ----------------------------------------------------------------- I'd like a bunch more comments, but if behaviour is kept and comments are added, this seems fine. ::: manifestdestiny/manifestparser/manifestparser.py @@ +425,5 @@ > > + if self.rootdir is None: > + rootdir = "" > + else: > + rootdir = self.rootdir + os.path.sep why `+ os.path.sep`? @@ +469,5 @@ > + # microoptimization, because relpath is quite expensive > + if path.startswith(rootdir): > + _relpath = path[len(rootdir):] > + else: > + _relpath = relpath(path, rootdir) Maybe worth busting out to a function?
Comment 15•11 years ago
|
||
> @@ +469,5 @@
> > + # microoptimization, because relpath is quite
> expensive
> > + if path.startswith(rootdir):
> > + _relpath = path[len(rootdir):]
> > + else:
> > + _relpath = relpath(path, rootdir)
> Maybe worth busting out to a function?
Scratch thate; probably better as is.
Comment 16•11 years ago
|
||
Comment on attachment 816723 [details] [diff] [review] optimize ManifestParser._read() path manipulations Review of attachment 816723 [details] [diff] [review]: ----------------------------------------------------------------- Sorry, I thought I r+ed this last week. Looks good! Thanks for the patch.
Attachment #816723 -
Flags: review?(jhammel) → review+
Comment 17•11 years ago
|
||
Comment on attachment 816725 [details] [diff] [review] fix preexisting manifestdestiny test failures on Windows. Review of attachment 816725 [details] [diff] [review]: ----------------------------------------------------------------- lgtm
Attachment #816725 -
Flags: review?(jhammel) → review+
Assignee | ||
Comment 18•11 years ago
|
||
Here is a patch with added comments, as requested in review. Can somebody please check this in for me, or set the checkin-needed keyword?
Attachment #820637 -
Flags: checkin?
Assignee | ||
Comment 19•11 years ago
|
||
Updated patch with added comments, and some additional tests to verify that this patch doesn't change the old behavior.
> why `+ os.path.sep`?
This is needed so that paths to sibling directories whose name has the same prefix as the manifest's directory don't get corrupt (e.g. manifest in /test, and a test with path ../test2/test would otherwise result in relpath 2/test). See also the added test and comment.
Attachment #820651 -
Flags: checkin?
Assignee | ||
Comment 20•11 years ago
|
||
Updated patch with review info in the commit message. I don't know if this is actually needed, is the process for commiting patches to mozbuild from non-commiters the same as for mozilla central, I just wait for some good soul to check it in for me?
Attachment #820665 -
Flags: checkin?
Comment 21•11 years ago
|
||
mozbase patches technically need to land in the github repository first.
Reporter | ||
Comment 22•11 years ago
|
||
Comment on attachment 820637 [details] [diff] [review] [gecko] fix O(tests * support-files) behaviour in _process_test_manifest (for checkin) Review of attachment 820637 [details] [diff] [review]: ----------------------------------------------------------------- https://hg.mozilla.org/integration/mozilla-inbound/rev/9dd234437dd1
Attachment #820637 -
Flags: checkin? → checkin+
Comment 23•11 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/9dd234437dd1
Assignee: nobody → ziga.seilnacht
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla27
Comment 24•11 years ago
|
||
Reopening, the mozbase parts still need to land. (To prevent automatic closure by mcMerge, use [leave open] in the bug whiteboard)
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Updated•11 years ago
|
Whiteboard: [checkin-needed-mozbase]
Updated•11 years ago
|
Attachment #816225 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #816723 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #816725 -
Attachment is obsolete: true
Updated•11 years ago
|
Attachment #820637 -
Attachment description: fix O(tests * support-files) behaviour in _process_test_manifest (for checkin) → [gecko] fix O(tests * support-files) behaviour in _process_test_manifest (for checkin)
Updated•11 years ago
|
Attachment #820651 -
Attachment description: optimize ManifestParser._read() path manipulations (for checkin) → [mozbase] optimize ManifestParser._read() path manipulations (for checkin)
Updated•11 years ago
|
Attachment #820665 -
Attachment description: fix preexisting manifestdestiny test failures on Windows (for checkin) → [mozbase] fix preexisting manifestdestiny test failures on Windows (for checkin)
Comment 25•11 years ago
|
||
No idea why this doesn't work, I'm not that familiar with git. manifestdestiny/tests/relative-path.ini doesn't exist in the mozbase repo already, so it's not like the patch just needs rebasing?! [/c/src/mozbase]$ git am ~/Desktop/import/* Applying: Bug 922517 - optimize ManifestParser._read() path manipulations, r=jhammel error: manifestdestiny/tests/relative-path.ini: already exists in working directory Patch failed at 0001 Bug 922517 - optimize ManifestParser._read() path manipulations, r=jhammel The copy of the patch that failed is found in: c:/src/mozbase/.git/rebase-apply/patch When you have resolved this problem, run "git am --resolved". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort".
Comment 26•11 years ago
|
||
(In reply to comment #25) > No idea why this doesn't work, I'm not that familiar with git. > > manifestdestiny/tests/relative-path.ini doesn't exist in the mozbase repo > already, so it's not like the patch just needs rebasing?! > > [/c/src/mozbase]$ git am ~/Desktop/import/* > Applying: Bug 922517 - optimize ManifestParser._read() path manipulations, > r=jhammel > error: manifestdestiny/tests/relative-path.ini: already exists in working > directory This means the file that the patch adds already exists as a file not tracked by git in your working directory. rm it and try again!
Comment 27•11 years ago
|
||
(In reply to :Ehsan Akhgari (needinfo? me!) [Away 10/29-11/6] from comment #26) > This means the file that the patch adds already exists as a file not tracked > by git in your working directory. rm it and try again! I did a |git reset --hard| immediately prior though?
Comment 28•11 years ago
|
||
Hmm I obviously misunderstood what git reset --hard does (I thought it was something similar to |hg revert -a && hg purge), since the file does indeed exist in the working directory. (My fault for not checking)
Comment 29•11 years ago
|
||
Comment on attachment 820651 [details] [diff] [review] [mozbase] optimize ManifestParser._read() path manipulations (for checkin) https://github.com/mozilla/mozbase/commit/ba8bace6a5ace578e5967b3b7c8afd13ec614c9f
Attachment #820651 -
Flags: checkin? → checkin+
Comment 30•11 years ago
|
||
Comment on attachment 820665 [details] [diff] [review] [mozbase] fix preexisting manifestdestiny test failures on Windows (for checkin) https://github.com/mozilla/mozbase/commit/526596737d77d72bea9a771a2292f2beecb9015e
Attachment #820665 -
Flags: checkin? → checkin+
Comment 31•11 years ago
|
||
Bug 930590 will deal with syncing from the github repo to the in-tree copy, but for now we're all done here. Thank you for the patches :-)
Status: REOPENED → RESOLVED
Closed: 11 years ago → 11 years ago
Resolution: --- → FIXED
Whiteboard: [checkin-needed-mozbase]
Updated•6 years ago
|
Product: Core → Firefox Build System
You need to log in
before you can comment on or make changes to this bug.
Description
•