-
Notifications
You must be signed in to change notification settings - Fork 174
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
Use "call" instead of "callBy" as much as possible to speed up the call to "KFunction". #403
Comments
Great idea and your English is perfectly easy to understand. We've got some performance tests for Jackson and some third party performance tests, neither of which I've ever run but would be interesting to see how this changes affects them. |
@dinomite It would be interesting to create Kotlin variant(s) of tests for I think having such variants would be quite useful and I can help if you think that makes sense. |
@dinomite What evidence do I need to incorporate this change? If needs only the simple |
Running jackson-benchmarks with the Kotlin module involved (which will require writing a new test in that project) before & after the change is probably sufficient to demonstrate this. I'm open to other suggestions as well, perhaps a performance test akin to those in |
For jmh tests I would suggest running under different profile (if in main repo), or changing this to multi-Maven module repo. On |
@dinomite @cowtowncoder data class TargetClazz(val foo: Int, val bar: Int, val baz: Int, val qux: Int, val quux: Int) {
companion object {
@JvmStatic
@JsonCreator
fun creator(
@JsonProperty("foo") foo: Int,
@JsonProperty("bar") bar: Int,
@JsonProperty("baz") baz: Int,
@JsonProperty("qux") qux: Int,
@JsonProperty("quux") quux: Int
) = TargetClazz(foo, bar, baz, qux, quux)
}
} @State(Scope.Benchmark)
open class Benchmarks {
private val javaMapper = ObjectMapper()
private val kotlinMapper = ObjectMapper().registerKotlinModule()
private val expected = TargetClazz(1, 2, 3, 4, 5)
private val input: ByteArray = javaMapper.writeValueAsBytes(expected)
@Benchmark
fun useJavaMapper(): TargetClazz = javaMapper.readValue(input, TargetClazz::class.java)
@Benchmark
fun useKotlinMapper(): TargetClazz = kotlinMapper.readValue(input, TargetClazz::class.java)
} The comparison is a slightly modified version of what I posted in this issue. The results of the Benchmark are as follows(Higher is better). before:
after:
options jmh {
fork = 3
iterations = 3
warmupBatchSize = 3
warmupIterations = 3
failOnError = true
isIncludeTests = false
resultFormat = "CSV"
} (I thought this solution would work for the whole mapping, but I found out that it actually only works for patterns like reading the |
I looked through the (Although it is off the subject, by converting |
@k163377 correct: there isn't yet any use of Overhead for constructor-passing variant comes from couple of things, including need to buffer values (instead directly assigning), and in case of Afterburner/Blackburner their inability (for now, at least) to optimize call of non-default constructors. |
Created a temporary pull request. |
@cowtowncoder @dinomite Would it be better to |
I'll go ahead and close this, we can track in the PRs. |
Use case
If the arguments are fully specified (= don't have to use
Default arguments
), can speed up the call tojackson-module-kotlin
by making a call withKFunction.call
.Describe the solution you'd like
Currently
jackson-module-kotlin
does mapping by callingKFunction.callBy
.On the other hand,
KFunction.callBy
has about 1/5 the performance ofKFunction.call
, so you can expect speedup by doingKFunction.call
as much as possible.Describe alternatives you've considered
For example, you can switch between
call
andcallBy
with low overhead by using the following data structure.This is used as follows (rewriting from line 134 of
KotlinValueInstantiator.kt
).Assuming that there are few situations where
Default arguments
is needed, I think that this alone can speed up the process.Additional context
I have published the contents as ProjectMapK/FastKFunction that incorporates further speed-up methods such as avoiding the spread operator and calling Java reflection directly, so I hope you can refer to that as well.
This is my first time posting issue and I am not good at English, so I'm sorry if there is something wrong with it.
The text was updated successfully, but these errors were encountered: