diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts index 2e4dd280..73dd8521 100644 --- a/benchmarks/build.gradle.kts +++ b/benchmarks/build.gradle.kts @@ -50,10 +50,11 @@ benchmark { warmups = 10 iterationTime = 100 iterationTimeUnit = "ms" - outputTimeUnit = "us" - mode = "avgt" + outputTimeUnit = "ms" + mode = "thrpt" // "thrpt" - throughput, "avgt" - average reportFormat = "text" // advanced("nativeGCAfterIteration", true) + // advanced("jvmForks", "definedByJmh") } } targets { diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelBasedMVIBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelTraditionalMVIBenchmark.kt similarity index 91% rename from benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelBasedMVIBenchmark.kt rename to benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelTraditionalMVIBenchmark.kt index 2cdd3359..5884e3ac 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelBasedMVIBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/channelbased/ChannelTraditionalMVIBenchmark.kt @@ -12,11 +12,10 @@ import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.State import pro.respawn.flowmvi.benchmarks.BenchmarkDefaults import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent -import pro.respawn.flowmvi.benchmarks.setup.optimized.optimizedStore @Suppress("unused") @State(Scope.Benchmark) -internal class ChannelBasedMVIBenchmark { +internal class ChannelTraditionalMVIBenchmark { lateinit var store: ChannelBasedTraditionalStore lateinit var scope: CoroutineScope diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoIntentBenchmark.kt similarity index 91% rename from benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoBenchmark.kt rename to benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoIntentBenchmark.kt index 272a923a..e084421a 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoIntentBenchmark.kt @@ -8,14 +8,15 @@ import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.State -import pro.respawn.flowmvi.api.Store +import org.openjdk.jmh.annotations.Threads import pro.respawn.flowmvi.benchmarks.BenchmarkDefaults import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent import pro.respawn.flowmvi.benchmarks.setup.BenchmarkState +@Threads(Threads.MAX) @Suppress("unused") @State(Scope.Benchmark) -internal class FluxoBenchmark { +internal class FluxoIntentBenchmark { lateinit var store: kt.fluxo.core.Store diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoStartStopBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoStartStopBenchmark.kt new file mode 100644 index 00000000..b720345a --- /dev/null +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/fluxo/FluxoStartStopBenchmark.kt @@ -0,0 +1,22 @@ +package pro.respawn.flowmvi.benchmarks.setup.fluxo + +import kotlinx.benchmark.Benchmark +import kotlinx.coroutines.runBlocking +import kt.fluxo.core.annotation.ExperimentalFluxoApi +import kt.fluxo.core.closeAndWait +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Threads + +@Threads(Threads.MAX) +@State(Scope.Benchmark) +class FluxoStartStopBenchmark { + + @OptIn(ExperimentalFluxoApi::class) + @Benchmark + fun benchmark() = runBlocking { + val store = fluxoStore() + store.start().join() + store.closeAndWait() + } +} diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIBenchmark.kt index f152180c..907300d5 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIBenchmark.kt @@ -1,24 +1,23 @@ package pro.respawn.flowmvi.benchmarks.setup.optimized import kotlinx.benchmark.TearDown -import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import org.openjdk.jmh.annotations.Benchmark -import org.openjdk.jmh.annotations.Fork import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Threads import pro.respawn.flowmvi.api.Store import pro.respawn.flowmvi.benchmarks.BenchmarkDefaults import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent import pro.respawn.flowmvi.benchmarks.setup.BenchmarkState import pro.respawn.flowmvi.dsl.collect +@Threads(Threads.MAX) @Suppress("unused") @State(Scope.Benchmark) internal class OptimizedFMVIBenchmark { diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIStartStopBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIStartStopBenchmark.kt new file mode 100644 index 00000000..e6d0e2fa --- /dev/null +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedFMVIStartStopBenchmark.kt @@ -0,0 +1,19 @@ +package pro.respawn.flowmvi.benchmarks.setup.optimized + +import kotlinx.benchmark.Benchmark +import kotlinx.coroutines.runBlocking +import org.openjdk.jmh.annotations.Scope +import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Threads + +@Threads(Threads.MAX) +@State(Scope.Benchmark) +internal class OptimizedFMVIStartStopBenchmark { + + @Benchmark + fun benchmark() = runBlocking { + val store = optimizedStore() + store.start(this).awaitStartup() + store.closeAndWait() + } +} diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedStore.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedStore.kt index 9c6fba40..8121eb50 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedStore.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/optimized/OptimizedStore.kt @@ -7,12 +7,12 @@ import pro.respawn.flowmvi.api.ActionShareBehavior.Disabled import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent.Increment import pro.respawn.flowmvi.benchmarks.setup.BenchmarkState +import pro.respawn.flowmvi.dsl.StoreBuilder import pro.respawn.flowmvi.dsl.store import pro.respawn.flowmvi.plugins.reduce +import pro.respawn.flowmvi.plugins.reducePlugin -internal inline fun optimizedStore( - scope: CoroutineScope, -) = store(BenchmarkState(), scope) { +internal fun StoreBuilder<*, *, *>.config() { configure { logger = null debuggable = false @@ -23,11 +23,24 @@ internal inline fun optimizedStore( onOverflow = BufferOverflow.DROP_OLDEST intentCapacity = Channel.RENDEZVOUS } - reduce { - when (it) { - is Increment -> updateStateImmediate { - copy(counter = counter + 1) - } +} + +private val reduce = reducePlugin { + when (it) { + is Increment -> updateStateImmediate { + copy(counter = counter + 1) } } } + +internal inline fun optimizedStore( + scope: CoroutineScope, +) = store(BenchmarkState(), scope) { + config() + install(reduce) +} + +internal inline fun optimizedStore() = store(BenchmarkState()) { + config() + install(reduce) +} diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/parallel/ParallelFMVIBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/parallel/ParallelFMVIBenchmark.kt index fdd50342..b15b90ff 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/parallel/ParallelFMVIBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/parallel/ParallelFMVIBenchmark.kt @@ -10,12 +10,14 @@ import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Threads import pro.respawn.flowmvi.api.Store import pro.respawn.flowmvi.benchmarks.BenchmarkDefaults import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent import pro.respawn.flowmvi.benchmarks.setup.BenchmarkState import pro.respawn.flowmvi.dsl.collect +@Threads(Threads.MAX) @Suppress("unused") @State(Scope.Benchmark) internal class ParallelFMVIBenchmark { diff --git a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/traditional/TraditionalMVIBenchmark.kt b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/traditional/TraditionalMVIBenchmark.kt index be5d8f46..558fedc9 100644 --- a/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/traditional/TraditionalMVIBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/pro/respawn/flowmvi/benchmarks/setup/traditional/TraditionalMVIBenchmark.kt @@ -6,9 +6,11 @@ import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Setup import org.openjdk.jmh.annotations.State +import org.openjdk.jmh.annotations.Threads import pro.respawn.flowmvi.benchmarks.BenchmarkDefaults import pro.respawn.flowmvi.benchmarks.setup.BenchmarkIntent +@Threads(Threads.MAX) @Suppress("unused") @State(Scope.Benchmark) internal class TraditionalMVIBenchmark {