I'm trying to squeeze every last bit of performanc...
# compiler
m
I'm trying to squeeze every last bit of performance out of the JVM for a mixed Java/Kotlin library that I maintain. Aside form Kotlin-specific features (such as inline functions), could we get some performance gains just by converting everything to Kotlin so that the Kotlin compiler might be able to make better optimizations?
y
That wouldn't necessarily do so much. You might get better IntelliJ refactorings when converting because you get to use stdlib methods. I'd recommend running your code through Proguard or something (while keeping function and class names), then decompile with cfr or similar, and read the decompiled code and see what could be improved)
j
I would expect performance to go down slightly if you port everything to Kotlin as the amount of intrinsic null checks will go up. You can, of course, mitigate that by turning most of them off, but then you run the risk of bad data propagating through your system from untrustworthy Java callers.
m
Untrustworthy callers aren't a very big concern because this library is such that an untrustworthy caller would really only hurt themselves. I've already gotten around the
!!
null checks. I have a no-op function with a contract that tells the compiler to assume that a value is non-null without actually checking it. Can you link to anything about turning off intrinsic null checks?
We're currently using Proguard for tree-shaking, but we turned off all other rewriting because something it was doing caused errors in Scala Build Tool when compiling Scala that has a dependency on our library.
y
I think ideally you'd run Proguard on the Scala binary instead. As in, you should only use Proguard when you're truly in a closed world
j
R8 is probably the better tool to use as it understands far more about Kotlin than ProGuard (at least as of a few years ago) and is not subject to many of the restrictions of ProGuard which supports very conservative output for really old Java VMs.
2
I don't know where the intrinsic flags are documented–I suspect nowhere. I always end up looking them up in the sources when I need to specify them. https://github.com/JetBrains/kotlin/blob/8fcf91d8efda8b84e468eb14633e4a5a1b9ac659/compiler/testData/cli/jvm/extraHelp.out#L96-L97
m
I tried R8, and ran into some problem with it that I no longer remember. I could give it another shot. However, we are still limited by having to support running on Java 8 VMs... hopefully that isn't too old for R8.
y
IIRC Android usually has to support around Java 8 or so. It even used to be the case that Java 6 support was needed.
e
current R8 itself needs a newer JVM I believe, but it should still target Java 8
j
Soren told me that it will keep the version you are using, and anything it produces will have a really low version like 50 or 52. Although in the past I've had problems running R8 on 21 and testing the output on Java 8. I usually just force R8 onto an older JDK to be safe.