koin icon indicating copy to clipboard operation
koin copied to clipboard

[optimization] Avoid unnecessary locking in single and scoped instances

Open JustinBis opened this issue 5 months ago • 0 comments

ScopedInstanceFactory and SingleInstanceFactory both lock on every call to get. This adds unnecessary overhead since locking is only required during the first initialization of an object.

Koin should add double-checked locking so that we can avoid locking every time we inject a single or scoped instance.

See Dagger's DoubleCheck for an example in Java that is widely employed: https://github.com/google/dagger/blob/f8a09b29683687720ae3e0e5ac241f3a4a054d6e/java/dagger/internal/DoubleCheck.java#L29

Example implementation

    // In SingleInstanceFactory
    @Volatile
    private var value: T? = null

    override fun get(context: InstanceContext): T {
        // Fast path to avoid locking if this instance is already initialized
        if (!isCreated(context)) {
            KoinPlatformTools.synchronized(this) {
                if (!isCreated(context)) {
                    value = create(context)
                }
            }
        }
        return getValue()
    }

Note that the multiplatform @Volatile is necessary for this to be correct on JVM and native platforms.

JustinBis avatar Sep 19 '24 23:09 JustinBis