-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
speed up precommit [LUCENE-9861] #10900
Comments
Robert Muir (@rmuir) (migrated from JIRA) For renderJavadoc this is also 2x speedup:
After:
I haven't yet attacked |
Robert Muir (@rmuir) (migrated from JIRA) My current hack patch. Still want to investigate Also I think we need not hardcode the args? I already have this stuff set correctly in It will be a little annoying for some things such as javadoc as we'll need to put |
Robert Muir (@rmuir) (migrated from JIRA) simple bench of current hack patch before:
after:
For reference, here are the task times from the output:
So I still need to investigate |
Dawid Weiss (@dweiss) (migrated from JIRA) You should really be looking at all dependencies of the "check -x test" task (checks without tests). Precommit is just a subset of those checks I typically run. As for javadoc - I had this crazy idea that it'd be great to combine multiple doclets into a single pass over the sources. Javadoc is repeating the job of javac (and multiple javadoc passes are doing it multiple time). It'd be great to reuse the compile tree somehow. Don't know how to do it but it sounds super hacky... I mean, exciting. |
Dawid Weiss (@dweiss) (migrated from JIRA) I did take a look at the patch... oh, man. There is a lovely way to pull it up - let me give it a try in an hour or so. |
Uwe Schindler (@uschindler) (migrated from JIRA) I would really like to look also into not forking a subprocess? Javac runs perfectly fine inside the Gradle JVM, why do we need to fork for each ECJ invocation? In Ant, ECJ used to run inside the Compiler Adapter of Ant and runs in-process. |
Robert Muir (@rmuir) (migrated from JIRA) Not forking is fine too. But forking with C2 enabled in order to run for only 5-20seconds is where things get bad (that's what we are doing today) |
Uwe Schindler (@uschindler) (migrated from JIRA) Yes, especially also renderJavadoc should use the better JVM options. RenderJavadoc can't be in-process, as javadoc calls System.exit(). But for stuff that works perfectly fine in the Gradle JVM, disabling forking also helps because it can run for very long time do class loading cost goes away, optimizer can optimize and Gradle daemon can keep it alive. |
Robert Muir (@rmuir) (migrated from JIRA) Also the "-times" can be removed from the patch. I was using it for debugging the ecj speed, but it would be noise to most people. |
Robert Muir (@rmuir) (migrated from JIRA)
In my tests it is better to run gradle's JVM with C1-only, too... even though it is longer lived. Maybe because of all the groovy and stuff, I'm not sure. Note: I don't use the daemon, but we are still talking about a process running for minutes and still C2 only slows things down. |
Dawid Weiss (@dweiss) (migrated from JIRA) I've refactored this into a somewhat more shared logic (see the PR). |
Dawid Weiss (@dweiss) (migrated from JIRA) The problem with running javadocs in-process is that I'm slightly worried about heap... we already have it quite high for gradle. Also, more importantly, javadoc is forked for the target JVM selected for compilation/ tests - this would be inconsistent if we used gradle's VM. |
Dawid Weiss (@dweiss) (migrated from JIRA) My results. After (sorry it was, the other way around): Aggregate task times (possibly running in parallel!):
77.53 sec. renderSiteJavadoc
76.72 sec. renderJavadoc
75.67 sec. compileJava
60.92 sec. compileTestJava
34.16 sec. ecjLintMain
30.85 sec. ecjLintTest
29.53 sec. checkBrokenLinks
29.18 sec. clean
24.42 sec. spotlessJava
...
BUILD SUCCESSFUL in 1m 47s Before: 136.29 sec. renderJavadoc
115.73 sec. renderSiteJavadoc
93.04 sec. compileJava
76.30 sec. compileTestJava
52.09 sec. ecjLintMain
48.96 sec. ecjLintTest
41.54 sec. spotlessJava
30.09 sec. clean
29.71 sec. checkBrokenLinks
12.31 sec. rat
10.65 sec. validateSourcePatterns
7.58 sec. checkUnusedConstraints
...
BUILD SUCCESSFUL in 2m 12s Wall-time difference isn't that big but this is an amd ryzen machine with lots of cores. |
Uwe Schindler (@uschindler) (migrated from JIRA) Looks slower after? 🤔 |
Robert Muir (@rmuir) (migrated from JIRA) If you have 87 cores, you can afford to spend a bunch of unused ones compiling c2 code to make the build go a few seconds faster. If you only have limited cores like me, when you run the build, computer is fully maxed out: you have 100% cpu usage. so cycles wasted on c2 add whole minutes to the build. |
Robert Muir (@rmuir) (migrated from JIRA) Another way to look at it, if you see that, you've set gradle parallelism too low and you have unused cores. Better to increase it so you are doing 64 of these things at a time than to only do 16 at a time and burn 48 cores on c2 :) |
Dawid Weiss (@dweiss) (migrated from JIRA) The improvement is clearly seen on individual tasks so I'm +1 for committing this in. I agree my work computer isn't representative - it's a beast (I love it). |
Uwe Schindler (@uschindler) (migrated from JIRA) +1 for committing |
ASF subversion and git services (migrated from JIRA) Commit 078d007 in lucene's branch refs/heads/main from Dawid Weiss LUCENE-9861: pull tuned vm options into a separate aspect. (#33) |
Robert Muir (@rmuir) (migrated from JIRA) Thank you @dweiss, this one really helps my computer. |
ASF subversion and git services (migrated from JIRA) Commit 078d007 in lucene's branch refs/heads/jira/LUCENE-9856-static-analysis from Dawid Weiss LUCENE-9861: pull tuned vm options into a separate aspect. (#33) |
Adrien Grand (@jpountz) (migrated from JIRA) Closing after the 9.0.0 release |
A lot of the java tools for precommit aren't being called in efficient ways (compilation, linting, etc).
For example ecjlint, it runs very slow:
Simplying adding a couple reasonable jvm arguments to the ecj linter (
jvmArgs = [ '-XX:+UseParallelGC', '-XX:TieredStopAtLevel=1' ]
) speeds it up significantly.Speedup for ecjLint is 3x for me:
I imagine same may be true for a lot of these tasks. We're currently tossing default jvm args at these short-lived subprocesses, which is very suboptimal.
Migrated from LUCENE-9861 by Robert Muir (@rmuir), resolved Mar 23 2021
Attachments: LUCENE-9861_hack.patch
Linked issues:
Pull requests: #33
The text was updated successfully, but these errors were encountered: