Closed andreaTP closed 2 years ago
The observed speedup on my local machine running in docker is about:
19-20 seconds
after ~11-12 seconds
I would be happy if someone from the maintainers can confirm or deny those numbers (and maybe test in an environment similar to prod).
Thanks a ton work for working on this! I'll have a look next week, I'm terribly busy at the moment.
@ErikSchierboom enjoy the weekend! 🙂
Wow. 1/3 speed-up already is really great @andreaTP!!
This is great :)
For the records, I have quickly attempted to use GraalVM native-image
For those of us not au fait, would you mind explaining a little more about what this would do pls?
Sure @iHiD !
Graal is an umbrella project from Oracle, one aspect of it is native-image
that enables producing binaries (as opposed to jars) for jvm projects, reducing a lot startup time.
The test runner has a lot in common with command line applications and it will probably benefits from running it as a binary.
@iHiD I hope this explains!
(Closed by mistake, sorry for the noise)
Quick update just to share the experience, (aka another failed experiment 🙂 ).
I thought that running the TestRunner
within Gradle itself(as a plugin) would save the additional JVM startup time.
A quick experiment (available here) demonstrates that this is not the case (back to ~16-17 seconds
), possibly due to Gradle plugins loading overhead.
The test runner has a lot in common with command line applications and it will probably benefits from running it as a binary.
Nice. That sounds useful indeed!
@andreaTP If I try to test this locally, I get the following error:
Exception in thread "main" java.nio.file.NoSuchFileException: build/test-results/test
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
at java.base/sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:432)
at java.base/java.nio.file.Files.newDirectoryStream(Files.java:472)
at com.google.common.io.MoreFiles.listFiles(MoreFiles.java:261)
at com.exercism.runner.TestRunner.run(TestRunner.java:49)
at com.exercism.runner.TestRunner.main(TestRunner.java:22)
Any ideas? How did you test on your machine?
@ErikSchierboom you are right indeed: here is the fix: https://github.com/exercism/java-test-runner/pull/37/commits/1cd917cfe8ac0bf576aa00d39bda9f4303f753ba
I was unconsciously relying on cached results 🙁 still this PR trim down execution times around ~14-15 seconds
per run.
@andreaTP Yes, that fixes it. I've tried to benchmark the differences but could not find any on my machine. Maybe I'm doing something wrong? I've tried to benchmark it by adding time
before the docker run
command in the run_in_docker.sh
command and then running ./run_in_docker.sh anagram $PWD/exercise $PWD/exercise
. Via this "benchmarking" I couldn't really find any difference between the current test runner and your PR. How did you test the performance?
Hey @ErikSchierboom , I was testing against bird-watcher
the same way you are doing, will have another look later.
Thanks for having a second look @ErikSchierboom ! I figured out that local caches have been tripping me 🙁 , to measure something meaningful I need something like this: https://github.com/andreaTP/java-test-runner/blob/06f0ad2ae6934765ef3d0b4fcfbda1cc94bcdf67/bin/run.sh#L25-L26 and with this, the performance is about the same as you correctly observed.
Takeaways:
gradle
performanceI will try to have another look but seems like you have already maxed the performance of this design ... What to try next?
I'm sorry that those experiments have failed, I'm available to have a chat on Slack about possible different approaches.
I think discussing things here is probably best, as we then have a public record of the things we've looked into, which makes it easier for other people
aggressive caching? (mounting external folders or in docker etc. etc.) What would be cached? Caching within Docker is perfectly fine, so if you have an idea what we could cache, let me know!
test using a different build tool (maven?)
I have no idea what the ramifications of that change would be, but if the test results are still the same, I'm fine with that. I'll leave it to @exercism/java to judge whether or not this is something to pursue.
increase the timeouts 😜 We can't really do that, as we're already at the maximum runtime we can allow on our infrastructure.
I've investigated a bit more:
aggressive caching
- attempted with
--build-cache
,--configuration-cache
and more: it's not effective
Basically, the very first gradle
invocation on a clean project takes 11-12 seconds(on my machine) to resolve the configuration (startup phase of gradle
itself).
Given all those failed attempts I'm drafting a PR to switch to Maven, exercism's builds are simple and pretty much constrained, of course, there are trade-offs, but might be worth giving this approach a spin!
Nice. Thanks @andreaTP!
Great! It's definitely worth a look.
This is the aggregated result of digging into: https://github.com/exercism/exercism/issues/6097
Feel free to ask me to split this into multiple PRs if you are uncomfortable merging such a big change, I will do it tomorrow.
I'll comment inline the motivation for the various changes.