Created
October 12, 2020 14:35
-
-
Save fluidsonic/d4a370bf742f8f9b801512d8777f533c to your computer and use it in GitHub Desktop.
Testing how fast Ktor client engines are in comparison
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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