Skip to content

Commit

Permalink
Merge pull request #1972 from InsertKoinIO/rework_core
Browse files Browse the repository at this point in the history
Clean up and optimise core internals core
  • Loading branch information
arnaudgiuliani authored Sep 12, 2024
2 parents 1546d27 + 809f8df commit cb91022
Show file tree
Hide file tree
Showing 52 changed files with 752 additions and 637 deletions.
1 change: 1 addition & 0 deletions examples/android-perfs/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package="org.koin.sample.android">

<application
android:name=".main.MainApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,47 @@ import kotlinx.coroutines.*
import org.koin.benchmark.PerfLimit
import org.koin.benchmark.PerfRunner.runAll
import org.koin.sample.android.R
import org.koin.sample.android.main.MainApplication.Companion.limits
import org.koin.sample.android.main.MainApplication.Companion.results
import kotlin.coroutines.CoroutineContext

class MainActivity : AppCompatActivity(), CoroutineScope {

override val coroutineContext: CoroutineContext = Job() + Dispatchers.Main
override val coroutineContext: CoroutineContext = Job() + Dispatchers.Default

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
title = "Android First Perfs"

runBlocking {
val limits = PerfLimit(10.8, 0.185)

println("Perf Tolerance: $limits")
}

val results = runAll(this)
results.applyLimits(limits)
val (startTime,execTime) = results
override fun onStart() {
super.onStart()
extractResults()
}

val textWidget = findViewById<TextView>(R.id.text)
var textReport = """
Start time: $startTime - max ${results.worstMaxStartTime} ms
Exec time: $execTime - max ${results.worstExecTime} ms
""".trimIndent()
private fun extractResults() {
println("Perf Tolerance: $limits")
val (startTime, execTime) = results!!
val ok = results!!.isOk

if (!results.isOk) textReport += "\nTest Failed!"
val textWidget = findViewById<TextView>(R.id.text)

textWidget.text = textReport
var textReport = """
Start time: $startTime - max ${results?.worstMaxStartTime} ms
Exec time: $execTime - max ${results?.worstExecTime} ms
""".trimIndent()

val color = if (!results.isOk) {
android.R.color.holo_red_dark
} else android.R.color.holo_green_dark
if (!ok) textReport += "\nTest Failed!"

textWidget.setTextColor(resources.getColor(color))
}
textWidget.text = textReport

val color = if (!ok) {
android.R.color.holo_red_dark
} else android.R.color.holo_green_dark

textWidget.setTextColor(resources.getColor(color))
}

override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.koin.sample.android.main

import android.app.Application
import kotlinx.coroutines.runBlocking
import org.koin.benchmark.PerfLimit
import org.koin.benchmark.PerfResult
import org.koin.benchmark.PerfRunner.runAll

class MainApplication : Application() {
override fun onCreate() {
super.onCreate()

runBlocking {
results = runAll(useDebugLogs = false)
results!!.applyLimits(limits)
}
}

companion object {
val limits = PerfLimit(27.0, 0.150)
var results : PerfResult? = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@ class TestPerfRunner {
* Avg start time: 13.06
* Avg execution time: 0.158
*/
// @Test
@Test
fun main() = runBlocking {
val limits = PerfLimit(17.0, 0.175)
// val limits = PerfLimit(10.0, 0.1)
// println("Perf target: $limits")

println("Perf Tolerance: $limits")

val results = PerfRunner.runAll(this)
results.applyLimits(limits)

assertTrue("Should start under ${results.worstMaxStartTime} ms", results.isStartOk)
assertTrue("Should exec under ${results.worstExecTime} ms", results.isExecOk)
val results = PerfRunner.runAll(useDebugLogs = false)
println("Perfs results: $results")
// results.applyLimits(limits)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import org.koin.core.context.startKoin
import org.koin.core.logger.Level
import org.koin.core.time.measureDuration
import org.koin.core.time.inMs
import kotlin.time.measureTime

class CoffeeApp : KoinComponent {
val maker: CoffeeMaker by inject()
Expand All @@ -17,8 +18,8 @@ fun main() {
}

val coffeeShop = CoffeeApp()
val duration = measureDuration {
val duration = measureTime {
coffeeShop.maker.brew()
}
println("Got Coffee in $duration ms")
println("Got Coffee in ${duration.inMs} ms")
}
2 changes: 1 addition & 1 deletion examples/gradle/versions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ext {
// Kotlin
kotlin_version = '2.0.20'
// Koin Versions
koin_version = '4.0.0-RC2'
koin_version = '4.0.0-RC3'
koin_android_version = koin_version
koin_compose_version = koin_version

Expand Down
8 changes: 4 additions & 4 deletions examples/jvm-perfs/benchmark.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Benchmark Mode Cnt Score Error Units
BenchmarkClass.emptyStart avgt 10 ≈ 10⁻⁴ ms/op
BenchmarkClass.flattenIterative avgt 10 0,544 ± 0,033 ms/op
BenchmarkClass.flattenRecursive avgt 10 0,318 ± 0,009 ms/op
BenchmarkClass.start400 avgt 10 0,219 ± 0,005 ms/op
BenchmarkClass.start400AndInject avgt 10 0,221 ± 0,007 ms/op
BenchmarkClass.flattenIterative avgt 10 0,533 ± 0,028 ms/op
BenchmarkClass.flattenRecursive avgt 10 0,283 ± 0,049 ms/op
BenchmarkClass.start400 avgt 10 0,206 ± 0,001 ms/op
BenchmarkClass.start400AndInject avgt 10 0,205 ± 0,003 ms/op
2 changes: 1 addition & 1 deletion examples/jvm-perfs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ tasks.getByName<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileKotlin"

val jmhVersion = "1.36"
//TODO get from existing version.gradle file
val koin_version = "3.6.0-Beta5"
val koin_version = "4.0.0-RC3"
val coroutines_version = "1.8.1"

dependencies {
Expand Down
46 changes: 20 additions & 26 deletions examples/jvm-perfs/src/main/kotlin/org/koin/benchmark/PerfRunner.kt
Original file line number Diff line number Diff line change
@@ -1,56 +1,50 @@
package org.koin.benchmark

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.koin.core.Koin
import org.koin.core.annotation.KoinExperimentalAPI
import org.koin.core.time.measureDurationForResult
import org.koin.core.logger.Level
import org.koin.core.time.inMs
import org.koin.dsl.koinApplication
import kotlin.math.roundToInt
import kotlin.time.measureTimedValue

object PerfRunner {

suspend fun runAll(scope: CoroutineScope): PerfResult {
val results = (1..10).map { i -> withContext(scope.coroutineContext) { runScenario(i) } }
fun runAll(useDebugLogs : Boolean = false): PerfResult {
val results = (1..10).map { i -> runScenario(i,useDebugLogs) }
val avgStart = (results.sumOf { it.first } / results.size).round(100)
val avgExec = (results.sumOf { it.second } / results.size).round(1000)
val avgExec = (results.sumOf { it.second } / results.size).round(10000)

println("Avg start: $avgStart ms")
println("Avg execution: $avgExec ms")
return PerfResult(avgStart,avgExec)
}

@OptIn(KoinExperimentalAPI::class)
fun runScenario(index: Int): Pair<Double, Double> {
val (app, duration) = measureDurationForResult {
fun runScenario(index: Int, useDebugLogs: Boolean): Pair<Double, Double> {
val appDuration = measureTimedValue {
koinApplication {
if (useDebugLogs){
printLogger(level = Level.DEBUG)
}
modules(
perfModule400()
)
}
}
println("Perf[$index] start in $duration ms")

val koin: Koin = app.koin

// runBlocking {
// koin.awaitAllStartJobs()
// }

val (_, executionDuration) = measureDurationForResult {
val koin: Koin = appDuration.value.koin
val scenarioDuration = measureTimedValue {
koinScenario(koin)
}
println("Perf[$index] run in $executionDuration ms")
app.close()
return Pair(duration, executionDuration)

val appDurationValue = appDuration.duration.inMs
val scenarioDurationValue = scenarioDuration.duration.inMs
println("Perf[$index] start in $appDurationValue ms")
println("Perf[$index] run in $scenarioDurationValue ms")

return Pair(appDurationValue, scenarioDurationValue)
}

fun koinScenario(koin: Koin){
koin.get<A27>()
koin.get<A31>()
koin.get<A12>()
koin.get<A42>()
}
}

Expand Down
1 change: 1 addition & 0 deletions projects/core/koin-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ kotlin {

sourceSets {
commonMain.dependencies {
implementation(kotlin("stdlib"))
implementation(libs.extras.stately)
implementation(libs.extras.stately.collections)
// api(libs.extras.uuid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ import org.koin.core.registry.PropertyRegistry
import org.koin.core.registry.ScopeRegistry
import org.koin.core.scope.Scope
import org.koin.core.scope.ScopeID
import org.koin.core.time.measureDuration
import org.koin.core.time.inMs
import org.koin.mp.KoinPlatformTools
import org.koin.mp.generateId
import kotlin.reflect.KClass
import kotlin.time.measureTime

/**
* Koin
Expand Down Expand Up @@ -327,9 +328,9 @@ class Koin {
*/
fun createEagerInstances() {
logger.debug("Create eager instances ...")
val duration = measureDuration {
val duration = measureTime {
instanceRegistry.createAllEagerInstances()
}
logger.debug("Created eager instances in $duration ms")
logger.debug("Created eager instances in ${duration.inMs} ms")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import org.koin.core.logger.Level
import org.koin.core.logger.Logger
import org.koin.core.module.KoinApplicationDslMarker
import org.koin.core.module.Module
import org.koin.core.time.measureDuration
import org.koin.core.time.inMs
import org.koin.mp.KoinPlatformTools
import kotlin.time.measureTime

/**
* Koin Application
Expand Down Expand Up @@ -58,9 +59,9 @@ class KoinApplication private constructor() {
*/
fun modules(modules: List<Module>): KoinApplication {
if (koin.logger.isAt(Level.INFO)) {
val duration = measureDuration { loadModules(modules) }
val duration = measureTime { loadModules(modules) }
val count = koin.instanceRegistry.size()
koin.logger.display(Level.INFO, "Started $count definitions in $duration ms")
koin.logger.display(Level.INFO, "Started $count definitions in ${duration.inMs} ms")
} else {
loadModules(modules)
}
Expand Down
Loading

0 comments on commit cb91022

Please sign in to comment.