Databinding is quite slow when domain implements traits
Opened this issue · 10 comments
We have observed that databinding runs quite slower when domain class implements traits.
I have attached the sample which shows the issue. Databinding runs quite slower (some time even 100% slower) on domains which implements traits.
Given a domain class
class City {
String name
String shortCode
String state
String country
BigDecimal latitude
BigDecimal longitude
}
@CompileStatic
trait CityTrait {
String name
String shortCode
String state
String country
BigDecimal latitude
BigDecimal longitude
}
class CityWithTrait implements CityTrait {
}
Given the City and CityWithTrait domain classes. The databinding the same props on CityWithTrait is quite slower compared to City.
Look at the attached example.
perftest-bug-report-17112017.zip
Create a runnable war, or run with bootrun.
The BootStrap runs the databinding on both of the sample domains for a million times and displays the time taken on console. Notice how slow the databinding on domain with trait it.
Bootstrap also manually sets the properties (using assignments) a 1 million time on both domains. Notice there is no big difference on how much time it takes.
So obviously it databinding which is some how getting affected by traits.
Environment Information
- Operating System: OSX
- Grails Version: 3.2.11
- JDK Version: 1.8
I am curious what could be going on in this case, if there is any hint, i would be glad to investigate / PR.
I tried few things, like if looking up props using reflection is slower on traits, but thats not the case.
Does marking CityWithTrait
with @CompileStatic
have a noticeable effect?
The linked zip file does not contain a buildable project. Some of the Gradle config is missing.
I have put a buildable version of the project at https://github.com/jeffbrown/issue10862.
you can see the trait slow down benchmark along with some other examples here https://github.com/9ci/grails-gorm-benchmarks
With https://github.com/jeffbrown/issue10862:
Took 12.721 seconds to databind domain City 100000 times
Took 12.396 seconds to databind domain City 100000 times
Took 11.196 seconds to databind domain StaticallyCompiledCity 100000 times
Took 10.791 seconds to databind domain StaticallyCompiledCity 100000 times
Took 19.161 seconds to databind domain CityWithTrait 100000 times
Took 18.954 seconds to databind domain CityWithTrait 100000 times
Took 16.75 seconds to databind domain StaticallyCompiledCityWithTrait 100000 times
Took 17.056 seconds to databind domain StaticallyCompiledCityWithTrait 100000 times
Took 1.303 seconds to manually set props on domain City 100000 times
Took 0.456 seconds to manually set props on domain StaticallyCompiledCity 100000 times
Took 1.372 seconds to manually set props on domain CityWithTrait 100000 times
Took 0.551 seconds to manually set props on domain StaticallyCompiledCityWithTrait 100000 times
The class at https://github.com/jeffbrown/issue10862/blob/50dc2bb070df7951865bdf2a81adb6b52d0a77b9/grails-app/domain/bugwork/CityWithNonFieldProperties.groovy demonstrates that the issue isn't really with traits per se but the way that property access works. Note that CityWithNonFieldProperties
performs about the same as CityWithTrait
.
Took 13.641 seconds to databind domain City 100000 times
Took 13.09 seconds to databind domain City 100000 times
Took 18.393 seconds to databind domain CityWithNonFieldProperties 100000 times
Took 19.077 seconds to databind domain CityWithNonFieldProperties 100000 times
Took 19.159 seconds to databind domain CityWithTrait 100000 times
Took 19.17 seconds to databind domain CityWithTrait 100000 times
Took 11.173 seconds to databind domain StaticallyCompiledCity 100000 times
Took 13.498 seconds to databind domain StaticallyCompiledCity 100000 times
Took 17.302 seconds to databind domain StaticallyCompiledCityWithNonFieldProperties 100000 times
Took 17.604 seconds to databind domain StaticallyCompiledCityWithNonFieldProperties 100000 times
Took 18.208 seconds to databind domain StaticallyCompiledCityWithTrait 100000 times
Took 19.212 seconds to databind domain StaticallyCompiledCityWithTrait 100000 times
Took 1.425 seconds to manually set props on domain City 100000 times
Took 1.426 seconds to manually set props on domain CityWithNonFieldProperties 100000 times
Took 1.581 seconds to manually set props on domain CityWithTrait 100000 times
Took 0.403 seconds to manually set props on domain StaticallyCompiledCity 100000 times
Took 0.42 seconds to manually set props on domain StaticallyCompiledCityWithNonFieldProperties 100000 times
Took 0.53 seconds to manually set props on domain StaticallyCompiledCityWithTrait 100000 times
Interesting, just curious, @jeffbrown any idea why would it take longer non field properties ?
When i tried, the dynamic lookup and setting value on property using MetaProperty dint have much difference in time it took, regardless if it is properties without fields.
Interesting, just curious, @jeffbrown any idea why would it take longer non field properties ?
No. Would need to profile it and figure out where the time is being spent.