Optimize CPointer.toKStringFromUtf8 on Native

Use strlen and stop allocating intermediate ByteArray
to make the performance comparable to ByteArray.decodeToString().

Partially fix KT-44357.
This commit is contained in:
Svyatoslav Scherbina
2021-02-16 19:03:18 +03:00
committed by Vasily Levchenko
parent dc2d014504
commit f766a3eae4
6 changed files with 33 additions and 14 deletions
@@ -21,9 +21,22 @@ import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
internal fun decodeFromUtf8(bytes: ByteArray) = String(bytes)
private fun decodeFromUtf8(bytes: ByteArray) = String(bytes)
internal fun encodeToUtf8(str: String) = str.toByteArray()
internal fun CPointer<ByteVar>.toKStringFromUtf8Impl(): String {
val nativeBytes = this
var length = 0
while (nativeBytes[length] != 0.toByte()) {
++length
}
val bytes = ByteArray(length)
nativeMemUtils.getByteArray(nativeBytes.pointed, bytes, length)
return decodeFromUtf8(bytes)
}
fun bitsToFloat(bits: Int): Float = java.lang.Float.intBitsToFloat(bits)
fun bitsToDouble(bits: Long): Double = java.lang.Double.longBitsToDouble(bits)
@@ -507,18 +507,7 @@ public val String.utf32: CValues<IntVar>
/**
* @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string.
*/
public fun CPointer<ByteVar>.toKStringFromUtf8(): String {
val nativeBytes = this
var length = 0
while (nativeBytes[length] != 0.toByte()) {
++length
}
val bytes = ByteArray(length)
nativeMemUtils.getByteArray(nativeBytes.pointed, bytes, length)
return decodeFromUtf8(bytes)
}
public fun CPointer<ByteVar>.toKStringFromUtf8(): String = this.toKStringFromUtf8Impl()
/**
* @return the [kotlin.String] decoded from given zero-terminated UTF-8-encoded C string.
@@ -20,9 +20,11 @@ import kotlin.native.internal.Intrinsic
import kotlin.native.internal.TypedIntrinsic
import kotlin.native.internal.IntrinsicType
internal fun decodeFromUtf8(bytes: ByteArray): String = bytes.decodeToString()
internal fun encodeToUtf8(str: String): ByteArray = str.encodeToByteArray()
@SymbolName("Kotlin_CString_toKStringFromUtf8Impl")
internal external fun CPointer<ByteVar>.toKStringFromUtf8Impl(): String
@TypedIntrinsic(IntrinsicType.INTEROP_BITS_TO_FLOAT)
external fun bitsToFloat(bits: Int): Float