Skip to content

Instantly share code, notes, and snippets.

@fluidsonic
Created October 12, 2020 14:35
Show Gist options
  • Save fluidsonic/d4a370bf742f8f9b801512d8777f533c to your computer and use it in GitHub Desktop.
Save fluidsonic/d4a370bf742f8f9b801512d8777f533c to your computer and use it in GitHub Desktop.
Testing how fast Ktor client engines are in comparison
import io.ktor.application.*
import io.ktor.client.*
import io.ktor.client.engine.*
import io.ktor.client.engine.apache.*
import io.ktor.client.engine.cio.*
import io.ktor.client.engine.jetty.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlin.system.*
import kotlin.time.*
import kotlinx.coroutines.*
import okhttp3.*
@OptIn(ExperimentalTime::class)
suspend fun main() = withContext(Dispatchers.Default) {
val batchCount = 200
val batchSize = 100
val threadCount = 100
val server = startServer()
delay(1_000)
val apache = Apache
val cio = CIO
val jetty = Jetty
val okHttp = OkHttp.config {
config {
addInterceptor { chain ->
chain.proceed(chain.request().newBuilder().header(HttpHeaders.AcceptEncoding, "").build())
}
protocols(listOf(Protocol.HTTP_1_1))
}
}
println("Benchmarking ${batchCount}x $batchSize parallel requests…")
for ((engineName, engine) in mapOf("Apache" to apache, "CIO" to cio, "Jetty" to jetty, "OkHttp" to okHttp)) {
HttpClient(engine) {
engine {
threadsCount = threadCount
}
}.use { client ->
repeat(2) { run ->
val time = measureTime {
repeat(batchCount) {
try {
withTimeout(10_000) {
coroutineScope {
repeat(batchSize) {
launch { client.get<HttpResponse>("http://localhost:8080").readText() }
}
}
}
} catch (e: TimeoutCancellationException) {
System.err.println("$engineName engine is not responding. Something is very wrong.")
exitProcess(-1)
} catch (e: Throwable) {
System.err.println("$engineName failed with an exception.")
e.printStackTrace()
exitProcess(-1)
}
}
}
if (run == 1)
println("$engineName: $time")
}
}
}
server.stop(0, 0)
}
private fun startServer() =
embeddedServer(Netty, port = 8080) {
val data = " ".repeat(64_000)
routing {
get("/") {
call.respondText(data, ContentType.Text.Plain)
}
}
}.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment