Skip to content

Commit

Permalink
Improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
memoizr committed Apr 23, 2019
1 parent d39b62a commit 74440c8
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 61 deletions.
12 changes: 6 additions & 6 deletions src/main/kotlin/com/memoizr/NewProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ package com.memoizr

import com.memoizr.ShankFactoryCache.factories

class NewProvider<T>(override val factory: () -> T) : Provider<T, () -> T> {
inline class NewProvider<T>(val i: Long) : Provider<T, () -> T> {
operator fun invoke(): T = factories[this].invokes()
}

class NewProvider1<A, T>(override val factory: (A) -> T) : Provider<T, (A) -> T> {
inline class NewProvider1<A, T>(val i: Long) : Provider<T, (A) -> T> {
operator fun invoke(a: A): T = factories[this].invokes(a)
}

class NewProvider2<A, B, T>(override val factory: (A, B) -> T) : Provider<T, (A, B) ->T> {
inline class NewProvider2<A, B, T>(val i: Long) : Provider<T, (A, B) ->T> {
operator fun invoke(a: A, b: B): T = factories[this].invokes(a, b)
}

class NewProvider3<A, B, C, T>(override val factory: (A, B, C) -> T) : Provider<T, (A, B, C) -> T> {
inline class NewProvider3<A, B, C, T>(val i: Long) : Provider<T, (A, B, C) -> T> {
operator fun invoke(a: A, b: B, c: C): T = factories[this].invokes(a, b, c)
}

class NewProvider4<A, B, C, D, T>(override val factory: (A, B, C, D) -> T) : Provider<T, (A, B, C, D) -> T> {
inline class NewProvider4<A, B, C, D, T>(val i: Long) : Provider<T, (A, B, C, D) -> T> {
operator fun invoke(a: A, b: B, c: C, d: D): T = factories[this].invokes(a, b, c, d)
}

class NewProvider5<A, B, C, D, E, T>(override val factory: (A, B, C, D, E) -> T) : Provider<T, (A, B, C, D, E) -> T> {
inline class NewProvider5<A, B, C, D, E, T>(val i: Long) : Provider<T, (A, B, C, D, E) -> T> {
operator fun invoke(a: A, b: B, c: C, d: D, e: E): T = factories[this].invokes(a, b, c, d, e)
}
57 changes: 41 additions & 16 deletions src/main/kotlin/com/memoizr/Provider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,65 @@ internal data class Params3(val a: Any?, val b: Any?, val c: Any?) : Params
internal data class Params4(val a: Any?, val b: Any?, val c: Any?, val d: Any?) : Params
internal data class Params5(val a: Any?, val b: Any?, val c: Any?, val d: Any?, val e: Any?) : Params

interface Provider<T, F : Function<T>> {
val factory: F
}
interface Provider<T, F : Function<T>>

fun <T, F : Function<T>> Provider<*, F>.factory(): F = factories[this] as F

fun <T, F : Function<T>> Provider<*, F>.restore() {
factories[this] = factory
factories[this] = factory()
}

fun <T, F : Function<T>> Provider<*, F>.overrideFactory(f: F) = remove()
.also { OverriddenCache.factories[this] = this.factory() }
.also { factories[this] = f }
.also { OverriddenCache.factories[this] = this.factory }

internal inline fun <T> Any?.invokes() = (Function0::class.java.cast(this)).invoke() as T
internal inline fun <A, T> Any?.invokes(a: A) = (this!! as Function1<A, T>).invoke(a)
internal inline fun <A, B, T> Any?.invokes(a: A, b: B) = (this!! as Function2<A, B, T>).invoke(a, b)
internal inline fun <A, B, C, T> Any?.invokes(a: A, b: B, c: C) = (this!! as Function3<A, B, C, T>).invoke(a, b, c)
internal inline fun <A, B, C, D, T> Any?.invokes(a: A, b: B, c: C, d: D) = (this!! as Function4<A, B, C, D, T>).invoke(a, b, c, d)
internal inline fun <A, B, C, D, E, T> Any?.invokes(a: A, b: B, c: C, d: D, e: E) = (this!! as Function5<A, B, C, D, E, T>).invoke(a, b, c, d, e)
internal inline fun <A, B, C, D, T> Any?.invokes(a: A, b: B, c: C, d: D) =
(this!! as Function4<A, B, C, D, T>).invoke(a, b, c, d)

internal inline fun <A, B, C, D, E, T> Any?.invokes(a: A, b: B, c: C, d: D, e: E) =
(this!! as Function5<A, B, C, D, E, T>).invoke(a, b, c, d, e)

internal inline fun <T> Any?.invokescoped(scope: ScopedFactory) = (this!! as ScopedFactory.() -> T).invoke(scope)
internal inline fun <A, T> Any?.invokescoped(scope: ScopedFactory, a: A) = (this!! as ScopedFactory.(A) -> T).invoke(scope, a)
internal inline fun <A, B, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B) = (this!! as ScopedFactory.(A, B) -> T).invoke(scope, a, b)
internal inline fun <A, B, C, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C) = (this!! as ScopedFactory.(A, B, C) -> T).invoke(scope, a, b, c)
internal inline fun <A, B, C, D, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C, d: D) = (this!! as ScopedFactory.(A, B, C, D) -> T).invoke(scope, a, b, c, d)
internal inline fun <A, B, C, D, E, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C, d: D, e: E) = (this!! as ScopedFactory.(A, B, C, D, E) -> T).invoke(scope, a, b, c, d, e)
internal inline fun <A, T> Any?.invokescoped(scope: ScopedFactory, a: A) =
(this!! as ScopedFactory.(A) -> T).invoke(scope, a)

internal inline fun <A, B, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B) =
(this!! as ScopedFactory.(A, B) -> T).invoke(scope, a, b)

private inline fun getScope(scope: Scope): MutableMap<Pair<Provider<*, *>, Params>, Any?>? = ShankCache.scopedCache[scope]
internal inline fun <A, B, C, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C) =
(this!! as ScopedFactory.(A, B, C) -> T).invoke(scope, a, b, c)

internal inline fun <A, B, C, D, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C, d: D) =
(this!! as ScopedFactory.(A, B, C, D) -> T).invoke(scope, a, b, c, d)

internal inline fun <A, B, C, D, E, T> Any?.invokescoped(scope: ScopedFactory, a: A, b: B, c: C, d: D, e: E) =
(this!! as ScopedFactory.(A, B, C, D, E) -> T).invoke(scope, a, b, c, d, e)

private inline fun getScope(scope: Scope): MutableMap<Pair<Provider<*, *>, Params>, Any?>? =
ShankCache.scopedCache[scope]

private inline fun Provider<*, *>.remove() {
ShankCache.scopedCache.forEach { scope -> scope.value.forEach { it -> if (it.key.first == this) { scope.value.remove(it.key) } } }
ShankCache.scopedCache.forEach { scope ->
scope.value.forEach { it ->
if (it.key.first == this) {
scope.value.remove(it.key)
}
}
}
}

internal inline fun <T, F : Function<T>> Provider<*, F>.get(scope: Scope, params: Params = Params0, f: Any?.() -> T): T {
if (getScope(scope) == null) { ShankCache.scopedCache[scope] = ConcurrentHashMap() }
internal inline fun <T, F : Function<T>> Provider<*, F>.get(
scope: Scope,
params: Params = Params0,
f: Any?.() -> T
): T {
if (getScope(scope) == null) {
ShankCache.scopedCache[scope] = ConcurrentHashMap()
}

return (getScope(scope)!!.let { newScope ->
val pair = Pair(this as Provider<out Any, Function<out Any>>, params)
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/com/memoizr/ScopedProvider.kt
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package com.memoizr

class ScopedProvider<T>(override val factory: ScopedFactory.() -> T) : Provider<T, ScopedFactory.() ->T> {
inline class ScopedProvider<T>(val i: Long) : Provider<T, ScopedFactory.() ->T> {
operator fun invoke(scope: Scope): T = get(scope) { invokescoped(ScopedFactory(scope)) }
}

class ScopedProvider1<A, T>(override val factory: ScopedFactory.(A) -> T) : Provider<T, ScopedFactory.(A) -> T> {
inline class ScopedProvider1<A, T>(val i: Long) : Provider<T, ScopedFactory.(A) -> T> {
operator fun invoke(scope: Scope, a: A): T = get(scope, Params1(a)) { invokescoped(ScopedFactory(scope), a) }
}

class ScopedProvider2<A, B, T>(override val factory: ScopedFactory.(A, B) -> T) : Provider<T, ScopedFactory.(A, B) ->T> {
inline class ScopedProvider2<A, B, T>(val i: Long) : Provider<T, ScopedFactory.(A, B) ->T> {
operator fun invoke(scope: Scope, a: A, b: B): T =
get(scope, Params2(a, b)) { invokescoped(ScopedFactory(scope), a, b) }
}

class ScopedProvider3<A, B, C, T>(override val factory: ScopedFactory.(A, B, C) -> T) : Provider<T, ScopedFactory.(A, B, C) -> T > {
inline class ScopedProvider3<A, B, C, T>(val i: Long) : Provider<T, ScopedFactory.(A, B, C) -> T > {
operator fun invoke(scope: Scope, a: A, b: B, c: C): T =
get(scope, Params3(a, b, c)) { invokescoped(ScopedFactory(scope), a, b, c) }
}

class ScopedProvider4<A, B, C, D, T>(override val factory: ScopedFactory.(A, B, C, D) -> T) : Provider<T,ScopedFactory.(A, B, C, D) -> T > {
inline class ScopedProvider4<A, B, C, D, T>(val i: Long) : Provider<T,ScopedFactory.(A, B, C, D) -> T > {
operator fun invoke(scope: Scope, a: A, b: B, c: C, d: D): T =
get(scope, Params4(a, b, c, d)) { invokescoped(ScopedFactory(scope), a, b, c, d) }
}

class ScopedProvider5<A, B, C, D, E, T>(override val factory: ScopedFactory.(A, B, C, D, E) -> T) : Provider<T, ScopedFactory.(A, B, C, D, E) -> T> {
inline class ScopedProvider5<A, B, C, D, E, T>(val i: Long) : Provider<T, ScopedFactory.(A, B, C, D, E) -> T> {
operator fun invoke(scope: Scope, a: A, b: B, c: C, d: D, e: E): T =
get(scope, Params5(a, b, c, d, e)) { invokescoped(ScopedFactory(scope), a, b, c, d, e) }
}
Expand Down
36 changes: 18 additions & 18 deletions src/main/kotlin/com/memoizr/ShankModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@ interface ShankModule

operator fun ShankModule.invoke(customize: ShankModule.() -> Unit) = also(customize)

fun <T> ShankModule.new(factory: () -> T) = NewProvider(factory).also { factories[it] = factory }
fun <A, T> ShankModule.new(factory: (A) -> T) = NewProvider1(factory).also { factories[it] = factory }
fun <A, B, T> ShankModule.new(factory: (A, B) -> T) = NewProvider2(factory).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.new(factory: (A, B, C) -> T) = NewProvider3(factory).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.new(factory: (A, B, C, D) -> T) = NewProvider4(factory).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.new(factory: (A, B, C, D, E) -> T) = NewProvider5(factory).also { factories[it] = factory }
fun <T> ShankModule.new(factory: () -> T) = NewProvider<T>(System.nanoTime()).also { factories[it] = factory }
fun <A, T> ShankModule.new(factory: (A) -> T) = NewProvider1<A, T>(System.nanoTime()).also { factories[it] = factory }
fun <A, B, T> ShankModule.new(factory: (A, B) -> T) = NewProvider2<A, B, T>(System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.new(factory: (A, B, C) -> T) = NewProvider3<A, B, C, T>(System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.new(factory: (A, B, C, D) -> T) = NewProvider4<A, B, C, D, T>(System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.new(factory: (A, B, C, D, E) -> T) = NewProvider5<A, B, C, D, E, T>(System.nanoTime()).also { factories[it] = factory }

fun <T> ShankModule.scoped(factory: ScopedFactory.() -> T) = ScopedProvider(factory).also { factories[it] = factory }
fun <A, T> ShankModule.scoped(factory: ScopedFactory.(A) -> T) = ScopedProvider1(factory).also { factories[it] = factory }
fun <A, B, T> ShankModule.scoped(factory: ScopedFactory.(A, B) -> T) = ScopedProvider2(factory).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C) -> T) = ScopedProvider3(factory).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C, D) -> T) = ScopedProvider4(factory).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C, D, E) -> T) = ScopedProvider5(factory).also { factories[it] = factory }
fun <T> ShankModule.scoped(factory: ScopedFactory.() -> T) = ScopedProvider<T> (System.nanoTime()).also { factories[it] = factory }
fun <A, T> ShankModule.scoped(factory: ScopedFactory.(A) -> T) = ScopedProvider1<A, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, T> ShankModule.scoped(factory: ScopedFactory.(A, B) -> T) = ScopedProvider2<A, B, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C) -> T) = ScopedProvider3<A, B, C, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C, D) -> T) = ScopedProvider4<A, B, C, D, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.scoped(factory: ScopedFactory.(A, B, C, D, E) -> T) = ScopedProvider5<A, B, C, D, E, T> (System.nanoTime()).also { factories[it] = factory }

fun <T> ShankModule.singleton(factory: () -> T) = SingletonProvider(factory).also { factories[it] = factory }
fun <A, T> ShankModule.singleton(factory: (A) -> T) = SingletonProvider1(factory).also { factories[it] = factory }
fun <A, B, T> ShankModule.singleton(factory: (A, B) -> T) = SingletonProvider2(factory).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.singleton(factory: (A, B, C) -> T) = SingletonProvider3(factory).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.singleton(factory: (A, B, C, D) -> T) = SingletonProvider4(factory).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.singleton(factory: (A, B, C, D, E) -> T) = SingletonProvider5(factory).also { factories[it] = factory }
fun <T> ShankModule.singleton(factory: () -> T) = SingletonProvider<T> (System.nanoTime()).also { factories[it] = factory }
fun <A, T> ShankModule.singleton(factory: (A) -> T) = SingletonProvider1<A, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, T> ShankModule.singleton(factory: (A, B) -> T) = SingletonProvider2<A, B, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, T> ShankModule.singleton(factory: (A, B, C) -> T) = SingletonProvider3<A, B, C, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, T> ShankModule.singleton(factory: (A, B, C, D) -> T) = SingletonProvider4<A, B, C, D, T> (System.nanoTime()).also { factories[it] = factory }
fun <A, B, C, D, E, T> ShankModule.singleton(factory: (A, B, C, D, E) -> T) = SingletonProvider5<A, B, C, D, E, T> (System.nanoTime()).also { factories[it] = factory }

24 changes: 12 additions & 12 deletions src/main/kotlin/com/memoizr/SingletonProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ package com.memoizr

import com.memoizr.ShankCache.globalScope

class SingletonProvider<T>(override val factory: () -> T) : Provider<T, () -> T> {
fun eager() = also { invoke() }
inline class SingletonProvider<T>(val i: Long) : Provider<T, () -> T> {
// fun eager() = also { invoke() }
operator fun invoke(): T = get(globalScope) { invokes() }
}

class SingletonProvider1<A, T>(override val factory: (A) -> T) : Provider<T, (A) -> T> {
fun eager(a: A) = also { invoke(a) }
inline class SingletonProvider1<A, T>(val i: Long) : Provider<T, (A) -> T> {
// fun eager(a: A) = also { invoke(a) }
operator fun invoke(a: A): T = get(globalScope, Params1(a)) { invokes(a) }
}

class SingletonProvider2<A, B, T>(override val factory: (A, B) -> T) : Provider<T, (A, B) -> T> {
fun eager(a: A, b: B) = also { invoke(a, b) }
inline class SingletonProvider2<A, B, T>(val i: Long) : Provider<T, (A, B) -> T> {
// fun eager(a: A, b: B) = also { invoke(a, b) }
operator fun invoke(a: A, b: B): T = get(globalScope, Params2(a, b)) { invokes(a, b) }
}

class SingletonProvider3<A, B, C, T>(override val factory: (A, B, C) -> T) : Provider<T, (A, B, C) -> T> {
fun eager(a: A, b: B, c: C) = also { invoke(a, b, c) }
inline class SingletonProvider3<A, B, C, T>(val i: Long) : Provider<T, (A, B, C) -> T> {
// fun eager(a: A, b: B, c: C) = also { invoke(a, b, c) }
operator fun invoke(a: A, b: B, c: C): T = get(globalScope, Params3(a, b, c)) { invokes(a, b, c) }
}

class SingletonProvider4<A, B, C, D, T>(override val factory: (A, B, C, D) -> T) : Provider<T, (A, B, C, D) -> T> {
fun eager(a: A, b: B, c: C, d: D) = also { invoke(a, b, c, d) }
inline class SingletonProvider4<A, B, C, D, T>(val i: Long) : Provider<T, (A, B, C, D) -> T> {
// fun eager(a: A, b: B, c: C, d: D) = also { invoke(a, b, c, d) }
operator fun invoke(a: A, b: B, c: C, d: D): T = get(globalScope, Params4(a, b, c, d)) { invokes(a, b, c, d) }
}

class SingletonProvider5<A, B, C, D, E, T>(override val factory: (A, B, C, D, E) -> T) : Provider<T, (A, B, C, D, E) -> T> {
fun eager(a: A, b: B, c: C, d: D, e: E) = also { invoke(a, b, c, d, e) }
inline class SingletonProvider5<A, B, C, D, E, T>(val i: Long) : Provider<T, (A, B, C, D, E) -> T> {
// fun eager(a: A, b: B, c: C, d: D, e: E) = also { invoke(a, b, c, d, e) }
operator fun invoke(a: A, b: B, c: C, d: D, e: E): T = get(globalScope, Params5(a, b, c, d, e)) { invokes(a, b, c, d, e) }
}
35 changes: 32 additions & 3 deletions src/test/kotlin/com/memoizr/PerformanceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,39 @@ import kotlin.system.measureNanoTime


class PerformanceTest {
object Moo {
// val a = System.nanoTime()
// val b = System.nanoTime()
// val c = System.nanoTime()
// val d = System.nanoTime()
// val e = System.nanoTime()
// val f = System.nanoTime()
// val g = System.nanoTime()
}

@Test
fun SimpleP() {
val x=measureTime {
// println(measureNanoTime {
// val x = AtomicInteger()
// x.incrementAndGet()
// x.incrementAndGet()
// x.incrementAndGet()
// x.incrementAndGet()
// x.incrementAndGet()
// x.incrementAndGet()
// x.incrementAndGet()
// })
// println(measureNanoTime {
//// val a = System.nanoTime()
//// val b = System.nanoTime()
//// val c = System.nanoTime()
//// val d = System.nanoTime()
//// val e = System.nanoTime()
//// val f = System.nanoTime()
//// val g = System.nanoTime()
// })

val x = measureTime {
fib8()
}

Expand All @@ -19,9 +48,9 @@ class PerformanceTest {

@Test
fun `performance`() {
val register= (1..100).map {
val register = (1..100).map {
measureTime {
// registerModules(Module1)
// registerModules(Module1)
}
}.median()

Expand Down

0 comments on commit 74440c8

Please sign in to comment.