Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running kotlin through JSR-223 is incredibly slow

Tags:

kotlin

jsr223

I'm running the following code and it's taking between 3 and 6 seconds to execute on both OSX (Sierra) and Windows 10. I've never seen such slowness using JSR-223, especially considering the simplicity of what's being evaluated. Digging through the call tree in YourKit it seems to be spending most of this time in KotlinJsr223JvmLocalScriptEngine.getReplEvaluator, but I can't see past that.

This is using jdk1.8.0_71 and kotlin 1.2.10.

Any ideas?

Thanks

import javax.script.ScriptEngineManager

fun main(args: Array<String>) {
    System.setProperty("idea.io.use.fallback", "true") // need this on windows, not required on osx it seems!
    val engine = ScriptEngineManager().getEngineByExtension("kts")!!

    val startTime = System.currentTimeMillis()

    engine.eval("val x = 5")

    println(System.currentTimeMillis() - startTime)
}

My build script is as follows:

buildscript {
    ext.kotlin_version = '1.2.10'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

group 'xxx'
version '1.0-SNAPSHOT'

apply plugin: 'kotlin'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile "org.jetbrains.kotlin:kotlin-script-util:$kotlin_version"
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
like image 269
L Morris Avatar asked Feb 13 '18 23:02

L Morris


2 Answers

I compared kotlin and groovy, both of which are precompiled: engine.compile(script)

Executing kotlin script via jsr223 is one hundred times slower than groovy script.

like image 97
kentchenj Avatar answered Oct 20 '22 22:10

kentchenj


The engine is lazy loaded so you are basically measuring the engine load time. Try doing the following before running your test.

val engine = ScriptEngineManager().getEngineByExtension("kts")
assert(engine.eval("true") as Boolean)

Also you should loop around a few times to get a better measure. Also you can pre-compile to make it faster. Also for real code you can return a lambda so you don't have to evaluate each time.

like image 41
lfmunoz Avatar answered Oct 20 '22 23:10

lfmunoz