Skip to content

ambco-iscte/kmemoize

Repository files navigation

KMemoize 🧠

Kotlin license - GNU GPLv3 tests Gradle Plugin Portal Version Maven Central Version

KMemoize is a Kotlin compiler plugin which enables quick-and-easy function memoization without the need for boilerplate code.

  • Functions are tagged with the @Memoize annotation.
  • Supports pure top-level, member, local, and anonymous functions :)
    • Impure functions can be forcibly memoized by using the @UnsafeMemoize annotation. This may lead to unintended behaviour!

🧠 Example

🔄 Help! My Function Is Recursive and I’m Calling It a Lot!

fun factorial(n: Int): Long =
    if (n == 0) 1L
    else n * factorial(n - 1)

@Memoize
fun factorialMemoized(n: Int): Long =
    if (n == 0) 1L
    else n * factorialMemoized(n - 1)

fun main() {
    val (value, time) = measureTimedValue { (1 .. 40000).sumOf { factorial(it) } }
    val (valueMemoized, timeMemoized) = measureTimedValue { (1 .. 40000).sumOf { factorialMemoized(it) } }
    println(value == valueMemoized)
    println("Non-memoized time: $time")
    println("Memoized time: $timeMemoized")
}

Console Output:

true
Non-memoized time: 1.483682300s
Memoized time: 10.784501ms

🔍 How Does It Work?

Internally, what's happening is that factorialMemoized is getting compiled to the equivalent of this code 👇

private val factorialMemoized234738315Memory: MutableMap<Int, Long> = 
    mutableMapOf<Int, Long>()

@Memoize
fun factorialMemoized(n: Int): Long {
    if (n !in factorialMemoized234738315Memory) {
        factorialMemoized234738315Memory[n] = 
            if (n == 0) 1L 
            else n * factorialMemoized(n - 1)
    }
    return factorialMemoized234738315Memory[n]!!
}

The weird 234738315 in factorialMemoized234738315Memory is just the hash code of the function's IR representation during compilation. This is just to avoid using existing identifiers.


⚙️ Setup

🐘 Gradle

Gradle Plugin Portal Version

plugins { 
    id("io.github.ambco-iscte.kmemoize") version "<kmemoize.version>"
}

dependencies {
    implementation("io.github.ambco-iscte:kmemoize.api:<kmemoize.version>")
}

🪶 Maven

Maven Central Version

<dependencies>
    <dependency>
        <groupId>io.github.ambco-iscte</groupId>
        <artifactId>kmemoize.api</artifactId>
        <version>${kmemoize.version}</version>
    </dependency>
</dependencies>

<build>
<plugins>
    <plugin>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-maven-plugin</artifactId>
        <version>2.2.0</version>

        <executions>
            <execution>
                <id>compile</id>
                <goals>
                    <goal>compile</goal>
                </goals>
                <configuration>
                    <compilerPlugins>
                        <plugin>kmemoize</plugin>
                    </compilerPlugins>
                </configuration>
            </execution>
        </executions>

        <dependencies>
            <dependency>
                <groupId>io.github.ambco-iscte</groupId>
                <artifactId>kmemoize.compiler</artifactId>
                <version>${kmemoize.version}</version>
            </dependency>
        </dependencies>
    </plugin>
</plugins>
</build>

About

🧠 An annotation-based Kotlin compiler plugin for function memoization.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages