
Drop-in replacement for java-diff-utils delivering ~10× faster diffing via hash-based snake detection, stable edge trimming, patience-style anchors, and primitive collections.
A drop-in replacement for java-diff-utils that is ~10× faster.
Fast Kotlin Diff Utils started as the change engine for ChangeDetection since java-diff-utils was causing UI freezes. By rewriting the core in Kotlin and applying profiling-driven optimizations (with help from Claude Opus 4.5, GPT-5.2, and Gemini 3 Pro), we achieved massive performance gains without changing the API.
On typical file diffs (2,000 lines, 10% edits), Fast Kotlin Diff Utils operates in microseconds where the original took milliseconds.
| Scenario | java-diff-utils | Fast Kotlin Diff Utils | Speedup |
|---|---|---|---|
DiffUtils.diff |
2.73 ms | 0.17 ms | ~16× |
| Custom Equalizer | 2.83 ms | 0.19 ms | ~15× |
patch.deltas access (500×) |
0.67 ms | 0.001 ms | ~670× |
We don't just run the same algorithm in proper Kotlin; we improved it:
equals() calls, skipping ~50% of comparisons.IntIntMap stores raw integers directly, avoiding the heavy memory overhead of allocating millions of Integer objects.dependencies {
implementation("io.github.bernaferrari:fast-kotlin-diff-core:1.0.0")
// Optional extensions:
// implementation("io.github.bernaferrari:fast-kotlin-diff-jvm-io:1.0.0") // Unified diff parsing/writing
// implementation("io.github.bernaferrari:fast-kotlin-diff-jgit:1.0.0") // Histogram diff via JGit
}The API is identical to java-diff-utils, so you can likely just change your imports.
Basic diff:
import com.bernaferrari.difflib.DiffUtils
val patch = DiffUtils.diff(original, revised)
val result = patch.applyTo(original)Side-by-side diff rows:
val generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.ignoreWhiteSpaces(true)
.build()
val rows = generator.generateDiffRows(originalLines, revisedLines)Complex comparison (Custom Equalizer):
// Compare objects by ID only, ignoring other fields
val patch = DiffUtils.diff(
users,
updatedUsers,
MyersDiff { a, b -> a.id == b.id }
)fast-kotlin-diff-core: The main library. Myers diff, patch apply/restore, diff-row generation. 100% Kotlin, Multiplatform-ready.fast-kotlin-diff-jvm-io: Unified diff parser/writer and Java serialization helpers. (JVM only).fast-kotlin-diff-jgit: Histogram diff adapter via Eclipse JGit.We welcome contributions!
./gradlew test
./gradlew :fast-kotlin-diff-bench:jmh
./gradlew spotlessCheck
There are other Kotlin ports of java-diff-utils:
These are straight ports—they convert the Java code to Kotlin but don't change the underlying algorithm. Fast Kotlin Diff Utils went further: we profiled real workloads, identified bottlenecks, and rewrote the core. The result is ~10× faster performance on typical diffs. If you're migrating from one of these, just update your imports to com.bernaferrari.difflib.*.
MIT — see LICENSE.
A drop-in replacement for java-diff-utils that is ~10× faster.
Fast Kotlin Diff Utils started as the change engine for ChangeDetection since java-diff-utils was causing UI freezes. By rewriting the core in Kotlin and applying profiling-driven optimizations (with help from Claude Opus 4.5, GPT-5.2, and Gemini 3 Pro), we achieved massive performance gains without changing the API.
On typical file diffs (2,000 lines, 10% edits), Fast Kotlin Diff Utils operates in microseconds where the original took milliseconds.
| Scenario | java-diff-utils | Fast Kotlin Diff Utils | Speedup |
|---|---|---|---|
DiffUtils.diff |
2.73 ms | 0.17 ms | ~16× |
| Custom Equalizer | 2.83 ms | 0.19 ms | ~15× |
patch.deltas access (500×) |
0.67 ms | 0.001 ms | ~670× |
We don't just run the same algorithm in proper Kotlin; we improved it:
equals() calls, skipping ~50% of comparisons.IntIntMap stores raw integers directly, avoiding the heavy memory overhead of allocating millions of Integer objects.dependencies {
implementation("io.github.bernaferrari:fast-kotlin-diff-core:1.0.0")
// Optional extensions:
// implementation("io.github.bernaferrari:fast-kotlin-diff-jvm-io:1.0.0") // Unified diff parsing/writing
// implementation("io.github.bernaferrari:fast-kotlin-diff-jgit:1.0.0") // Histogram diff via JGit
}The API is identical to java-diff-utils, so you can likely just change your imports.
Basic diff:
import com.bernaferrari.difflib.DiffUtils
val patch = DiffUtils.diff(original, revised)
val result = patch.applyTo(original)Side-by-side diff rows:
val generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.ignoreWhiteSpaces(true)
.build()
val rows = generator.generateDiffRows(originalLines, revisedLines)Complex comparison (Custom Equalizer):
// Compare objects by ID only, ignoring other fields
val patch = DiffUtils.diff(
users,
updatedUsers,
MyersDiff { a, b -> a.id == b.id }
)fast-kotlin-diff-core: The main library. Myers diff, patch apply/restore, diff-row generation. 100% Kotlin, Multiplatform-ready.fast-kotlin-diff-jvm-io: Unified diff parser/writer and Java serialization helpers. (JVM only).fast-kotlin-diff-jgit: Histogram diff adapter via Eclipse JGit.We welcome contributions!
./gradlew test
./gradlew :fast-kotlin-diff-bench:jmh
./gradlew spotlessCheck
There are other Kotlin ports of java-diff-utils:
These are straight ports—they convert the Java code to Kotlin but don't change the underlying algorithm. Fast Kotlin Diff Utils went further: we profiled real workloads, identified bottlenecks, and rewrote the core. The result is ~10× faster performance on typical diffs. If you're migrating from one of these, just update your imports to com.bernaferrari.difflib.*.
MIT — see LICENSE.