marcinmoskala
10/03/2021, 5:11 PMmarcinmoskala
10/03/2021, 5:48 PM@State(Scope.Benchmark)
open class KotlinBenchmark {
private val orders: List<Order> = List(100) { Order("Customer$it") }
private val singleThread = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
private val e100Threads = Executors.newFixedThreadPool(100).asCoroutineDispatcher()
@Benchmark
fun defaultCpu1(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, Dispatchers.Default, ::cpu1))
}
@Benchmark
fun defaultCpu2(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, Dispatchers.Default, ::cpu2))
}
@Benchmark
fun defaultBlocking(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, Dispatchers.Default, ::blocking))
}
@Benchmark
fun defaultSuspending(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, Dispatchers.Default, ::suspending))
}
@Benchmark
fun e100ThreadsCpu1(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, e100Threads, ::cpu1))
}
@Benchmark
fun e100ThreadsCpu2(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, e100Threads, ::cpu2))
}
@Benchmark
fun e100ThreadsBlocking(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, e100Threads, ::blocking))
}
@Benchmark
fun e100ThreadsSuspending(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, e100Threads, ::suspending))
}
@Benchmark
fun singleThreadCpu1(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, singleThread, ::cpu1))
}
@Benchmark
fun singleThreadCpu2(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, singleThread, ::cpu2))
}
@Benchmark
fun singleThreadBlocking(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, singleThread, ::blocking))
}
@Benchmark
fun singleThreadSuspending(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, singleThread, ::suspending))
}
@Benchmark
fun ioCpu1(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, <http://Dispatchers.IO|Dispatchers.IO>, ::cpu1))
}
@Benchmark
fun ioCpu2(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, <http://Dispatchers.IO|Dispatchers.IO>, ::cpu2))
}
@Benchmark
fun ioBlocking(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, <http://Dispatchers.IO|Dispatchers.IO>, ::blocking))
}
@Benchmark
fun ioSuspending(bh: Blackhole) = runBlocking {
bh.consume(makeCoffee(orders, <http://Dispatchers.IO|Dispatchers.IO>, ::suspending))
}
}
class Order(val customer: String)
class Coffee(val order: Order)
suspend fun makeCoffee(
orders: List<Order>,
dispatcher: CoroutineDispatcher,
makeCoffee: suspend (Order)->Coffee
) = withContext(dispatcher) {
orders.map { async { makeCoffee(it) } }
.map { it.join() }
}
fun cpu1(order: Order): Coffee {
val size = 350 // ~0.1 second on my MacBook
val list = List(size) { it }
val listOfLists = List(size) { list }
val listOfListsOfLists = List(size) { listOfLists }
listOfListsOfLists.hashCode()
return Coffee(order)
}
fun cpu2(order: Order): Coffee {
val size = 820 // ~1 second on my MacBook
val list = List(size) { it }
val listOfLists = List(size) { list }
val listOfListsOfLists = List(size) { listOfLists }
listOfListsOfLists.hashCode()
return Coffee(order)
}
fun blocking(order: Order): Coffee {
Thread.sleep(1000)
return Coffee(order)
}
suspend fun suspending(order: Order): Coffee {
delay(1000)
return Coffee(order)
}
marcinmoskala
10/03/2021, 5:49 PMBenchmark Mode Cnt Score Error Units
KotlinBenchmark.defaultBlocking thrpt 5 0.077 ± 0.001 ops/s
KotlinBenchmark.defaultCpu1 thrpt 5 0.157 ± 0.100 ops/s
KotlinBenchmark.defaultCpu2 thrpt 5 0.009 ± 0.002 ops/s
KotlinBenchmark.defaultSuspending thrpt 5 0.998 ± 0.002 ops/s
KotlinBenchmark.e100ThreadsBlocking thrpt 5 0.997 ± 0.003 ops/s
KotlinBenchmark.e100ThreadsCpu1 thrpt 5 0.173 ± 0.024 ops/s
KotlinBenchmark.e100ThreadsCpu2 thrpt 5 0.012 ± 0.002 ops/s
KotlinBenchmark.e100ThreadsSuspending thrpt 5 0.998 ± 0.004 ops/s
KotlinBenchmark.ioBlocking thrpt 5 0.499 ± 0.001 ops/s
KotlinBenchmark.ioCpu1 thrpt 5 0.185 ± 0.038 ops/s
KotlinBenchmark.ioCpu2 thrpt 5 0.012 ± 0.006 ops/s
KotlinBenchmark.ioSuspending thrpt 5 0.998 ± 0.003 ops/s
KotlinBenchmark.singleThreadBlocking thrpt 5 0.010 ± 0.001 ops/s
KotlinBenchmark.singleThreadCpu1 thrpt 5 0.067 ± 0.006 ops/s
KotlinBenchmark.singleThreadCpu2 thrpt 5 0.005 ± 0.001 ops/s
KotlinBenchmark.singleThreadSuspending thrpt 5 0.998 ± 0.005 ops/s
SampleBenchmark.fibClassic thrpt 5 417.312 ± 4.514 ops/s
SampleBenchmark.fibTailRec thrpt 5 51156850.491 ± 556032.508 ops/s
DALDEI
10/04/2021, 12:32 AMErik
10/05/2021, 5:14 AMErik
10/05/2021, 5:16 AMErik
10/05/2021, 5:19 AMErik
10/05/2021, 5:34 AMvar i = Int.MAX_VALUE // ~25 seconds on my Macbook
while (i > 0) i -= 1
marcinmoskala
10/18/2021, 4:39 PMvar i = Int.MAX_VALUE // ~25 seconds on my Macbook
while (i > 0) i -= 1
was optimized on low-level. The second function is checking for different numbers if they are prime numbers or not.
The results are now much more as expected.
https://kt.academy/article/cc-dispatchers#performance-of-dispatchers-against-different-tasks
Does it look good now?DALDEI
10/18/2021, 10:57 PMDALDEI
10/18/2021, 11:12 PM