-
-
Notifications
You must be signed in to change notification settings - Fork 969
Description
Issue description
We upgraded a large and data-intensive application from Grails 6.2.3 to Grails 7 but noticed a significant performance regression reaching 4x on some operations.
We suspect this is related to Groovy 4's "indy" approach and GORM suffering from that more than expected.
It's not noticeable at first sight. I couldn't come up with a simple example where such a big regression would be noticeable so I ended up using an LLM to generate a small application with a method doing something on the data using GORM.
It's a bunch of domains (Company, Department, Employee, Milestone, Project, Skill, Task) with associations and an initial dataset. Uses H2 dev database for simplicity.
I really hope I haven't missed anything obvious (some optimisation or flag, hibernate cache is disabled in both) and this is indeed a Groovy 4 regression.
- With 50 iterations (and 5 warmup iterations) I observed the same
4xregression. - with
-Dgroovy.indy.optimize.threshold=0 -Dgroovy.indy.fallback.threshold=0it's only ~2x as bad but it's not entirely clear how to use that, other combinations didn't yield results as good - when looking at flame graphs unsurprisingly Grails 7 is full of
org.codehaus.groovy.vmplugin.v8.*where Grails 6 is usingorg.codehaus.groovy.runtime.* - @CompileStatic hasn't been explored as it requires code changes that I would really like to avoid
- benchmarks were done with
:bootWar, embedded tomcat with-Dgrails.env=developmentbut:bootRunis8xslower than Grails 6, and3xslower than Grails 7 bootWar - so development mode in IDE is also hit
At the moment we've had to stop and revert the migration as a 4x performance hit is hard to swallow.
From groovy4: https://groovy-lang.org/releasenotes/groovy-4.0.html#Groovy4.0-consolidation
Currently, the Groovy runtime still contains any necessary support for classes compiled using older versions of Groovy. Please use Groovy versions up to 3.x if you need to generate the older style bytecode.
This work was originally planned for Groovy 3.0, but there were numerous places where "indy" code was noticeably slower than "classic" bytecode. We have made numerous speed improvements (starting with [GROOVY-8298](https://issues.apache.org/jira/browse/GROOVY-8298)) and have some ability to tune internal thresholds (search the code base for groovy.indy.optimize.threshold and groovy.indy.fallback.threshold). That work gave us useful speed improvements, but we welcome further feedback to help improve overall performance of the indy bytecode.
Is there any chance this can be further optimised or could Grails 7 potentially work with Groovy 3?
Link to the benchmark applications: https://github.com/jglapa/grails7-performance-regression
Metadata
Metadata
Assignees
Labels
Type
Projects
Status