--
You received this message because you are subscribed to the Google Groups "gradle-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gradle-dev+...@googlegroups.com.
To post to this group, send email to gradl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gradle-dev/2f81e522-49af-4595-afe9-b43deb0a3ff6%40googlegroups.com.
Hi Ben,It's great to get a reply from the author. ConcurrentLinkedHashMap is used in Grails for many internal caches, since 2010 (Marco Vermeulen's commit https://github.com/grails/grails-core/commit/55cf993b introduced it to Grails).
CLHM is great. However the feature I miss from CLHM is the CacheLoader interface that Guava Cache has. Using putIfAbsent is ugly.
Asynchrously refreshing expired values is a cool feature of Guava Cache as well, however that's not used in Gradle.I don't have a separate benchmark in Gradle that shows the evidence that Guava Cache is a bottleneck. I'd like to do some JMH benchmarks for measuring, but I haven't done that (yet).
I've been profiling a Gradle build that we have in our performance tests. The test build has about 100000 source files and 100000 test source files in 99 sub-projects. There are also project dependencies and external dependencies. ("./gradlew :performance:largeJavaSwModelProject" generates the build to subprojects/performance/build/largeJavaSwModelProject in gradle core).
In the profiling I noticed that Guava Cache was showing up in the hotspots and I tried replacing Guava Cache with ConcurrentLinkedHashMap. The surprise was that I got 5-10% better results (shorter build time). I'd have to try the measurement once more to be sure about the improvement. It makes me wonder about it because Gradle has explicit locking around caches because of in-memory caches are just decorators around persistent caches that have to be guarded by an explicit lock when they are accessed.
I've been using Java Flight Recorder to do the profiling since that seems to work best for this case. I'm also using the "-XX:+DebugNonSafepoints" flag and that seems to help in getting more useful information.
I've used these JVM options for enabling Flight recorder:
export GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx8g -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints'"and using these scripts and JFR profile: https://github.com/lhotari/gradle-profiling/tree/master/jfr to get the dumps.To analyze the profiling results, I'm using JMC and besides that I'm using Brendan Gregg's Flame Graphs (https://github.com/brendangregg/FlameGraph) to visualize the stack trace samples. I've have a custom tool https://github.com/lhotari/jfr-report-tool to get the relevant data from the JFR dump to the Flame Graph tool.There is currently another cache in release branch that also uses Guava Cache.
https://github.com/gradle/gradle/blob/f77a4b6556558c9c169039fc0f4d366d720afc6b/subprojects/core/src/main/groovy/org/gradle/api/tasks/util/internal/CachingPatternSpecFactory.java#L42-L43
The hit rates on that cache is very high for Gradle builds with a lot of files. I haven't tried to replace that with other implementations like ConcurrentLinkedHashMap. I'd rather not use CLHM because it doesn't have the CacheLoader support that Guava Cache has.
To view this discussion on the web visit https://groups.google.com/d/msgid/gradle-dev/CAK_qiZcgqW-y6TW0ZT2fKdbOn5SXTCWfA06y-GNfExgcUzuXxQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gradle-dev/689dae24-5fcf-4399-be6b-594cc91e8d17%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.