Skip to content

Commit

Permalink
perf: do not use expensive transformation functions in critical code
Browse files Browse the repository at this point in the history
Relates-to: Strumenta#49
  • Loading branch information
lppedd committed Dec 6, 2023
1 parent ecf420c commit 45bc85c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.strumenta.kotlinmultiplatform

object Math {
fun min(a: Int, b: Int): Int =
inline fun min(a: Int, b: Int): Int =
kotlin.math.min(a, b)

fun max(a: Int, b: Int): Int =
inline fun max(a: Int, b: Int): Int =
kotlin.math.max(a, b)

fun floor(d: Double): Double =
inline fun floor(d: Double): Double =
kotlin.math.floor(d)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.strumenta.kotlinmultiplatform.ext

fun String.codePointIndices(): IntArray {
val intArray = IntArray(length)
var p = 0

for (i in indices) {
if (!hasSurrogatePairAt(i - 1)) {
intArray[p++] = i
}
}

return intArray.copyOfRange(0, p)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,82 @@ package org.antlr.v4.kotlinruntime

import com.strumenta.kotlinmultiplatform.Math
import com.strumenta.kotlinmultiplatform.assert
import com.strumenta.kotlinmultiplatform.ext.codePointIndices
import org.antlr.v4.kotlinruntime.misc.Interval

internal fun String.codePointIndices(): IntArray {
return (0 until length).mapNotNull { index ->
if (hasSurrogatePairAt(index - 1)) {
null
} else {
index
}
}.toIntArray()
}

private fun toCodePoint(high: Char, low: Char): Int {
return high.toInt().shl(10) + low.toInt() + -56613888
}

class StringCharStream(private val source: String, override val sourceName: String) : CharStream {
private val codePointIndices = source.codePointIndices()
private val size = codePointIndices.size
private var position: Int = 0

private fun codePoint(index: Int): Int {
return if (index in 0 until size) {
val char = source[codePointIndices[index]]
if (char.isHighSurrogate()) {
if (index + 1 in 0 until size) {
val low = source[codePointIndices[index] + 1]
toCodePoint(char, low)
} else {
IntStream.EOF
}
} else {
char.toInt()
}
} else {
IntStream.EOF
}
}
private var position = 0

override fun consume() {
if (size - position == 0) {
assert(LA(1) == IntStream.EOF)
throw IllegalStateException("cannot consume EOF")
}
position += 1
}

override fun index(): Int {
return position
position++
}

override fun size(): Int {
return size
}
override fun index(): Int =
position

/** mark/release do nothing; we have entire buffer */
override fun mark(): Int {
return -1
}
override fun size(): Int =
size

/**
* Does nothing, as we have the entire buffer.
*/
override fun mark(): Int =
-1

/**
* Does nothing, as we have the entire buffer.
*/
override fun release(marker: Int) {
// Noop
}

override fun seek(index: Int) {
position = index
}

override fun toString(): String {
return getText(Interval.of(0, size - 1))
}
override fun toString(): String =
getText(Interval.of(0, size - 1))

override fun getText(interval: Interval): String {
val startIndex = Math.min(interval.a, size)
val endIndex = Math.min(interval.b, size)
return source.substring(codePointIndices[startIndex], codePointIndices[endIndex] + 1)
}

override fun LA(i: Int): Int {
return when {
override fun LA(i: Int): Int =
when {
i < 0 -> codePoint(position + i)
i > 0 -> codePoint(position + i - 1)
else ->
// Undefined
return 0
// Undefined
else -> 0
}

private fun codePoint(index: Int): Int {
if (index !in 0..<size) {
return IntStream.EOF
}

val char = source[codePointIndices[index]]

if (char.isHighSurrogate()) {
if (index + 1 in 0..<size) {
val low = source[codePointIndices[index] + 1]
return toCodePoint(char, low)
}

return IntStream.EOF
}

return char.code
}

private fun toCodePoint(high: Char, low: Char): Int =
(high.code shl 10) + low.code + (-56613888)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.antlr.v4.kotlinruntime

import BaseTest
import com.strumenta.kotlinmultiplatform.ext.codePointIndices
import org.antlr.v4.kotlinruntime.misc.Interval
import kotlin.test.Test

Expand Down

0 comments on commit 45bc85c

Please sign in to comment.