Optimize important case of string appending to the builder. (#1591)
This commit is contained in:
@@ -840,6 +840,30 @@ OBJ_GETTER(Kotlin_String_plusImpl, KString thiz, KString other) {
|
||||
RETURN_OBJ(result->obj());
|
||||
}
|
||||
|
||||
KInt Kotlin_StringBuilder_insertString(KRef builder, KInt position, KString fromString) {
|
||||
auto toArray = builder->array();
|
||||
RuntimeAssert(toArray->count_ >= fromString->count_ + position, "must be true");
|
||||
memcpy(CharArrayAddressOfElementAt(toArray, position),
|
||||
CharArrayAddressOfElementAt(fromString, 0),
|
||||
fromString->count_ * sizeof(KChar));
|
||||
return fromString->count_;
|
||||
}
|
||||
|
||||
KInt Kotlin_StringBuilder_insertInt(KRef builder, KInt position, KInt value) {
|
||||
auto toArray = builder->array();
|
||||
RuntimeAssert(toArray->count_ >= 11 + position, "must be true");
|
||||
char cstring[12];
|
||||
auto length = konan::snprintf(cstring, sizeof(cstring), "%d", value);
|
||||
auto* from = &cstring[0];
|
||||
auto* to = CharArrayAddressOfElementAt(toArray, position);
|
||||
auto* end = from + length;
|
||||
while (from != end) {
|
||||
*to++ = *from++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
KBoolean Kotlin_String_equals(KString thiz, KConstRef other) {
|
||||
if (other == nullptr || other->type_info() != theStringTypeInfo) return false;
|
||||
// Important, due to literal internalization.
|
||||
|
||||
@@ -65,6 +65,12 @@ private external fun String.toUtf8OrThrowImpl(start: Int, size: Int) : ByteArray
|
||||
@SymbolName("Kotlin_String_fromCharArray")
|
||||
external fun fromCharArray(array: CharArray, start: Int, size: Int) : String
|
||||
|
||||
@SymbolName("Kotlin_StringBuilder_insertString")
|
||||
private external fun insertString(array: CharArray, start: Int, value: String): Int
|
||||
|
||||
@SymbolName("Kotlin_StringBuilder_insertInt")
|
||||
private external fun insertInt(array: CharArray, start: Int, value: Int): Int
|
||||
|
||||
/**
|
||||
* Builds new string by populating newly created [StringBuilder] using provided [builderAction]
|
||||
* and then converting it to [String].
|
||||
@@ -253,8 +259,15 @@ class StringBuilder private constructor (
|
||||
return this
|
||||
}
|
||||
|
||||
fun insert(index: Int, string: String): StringBuilder = insert(index, string.toCharArray())
|
||||
fun insert(index: Int, string: String): StringBuilder {
|
||||
checkInsertIndex(index)
|
||||
ensureExtraCapacity(string.length)
|
||||
array.copyRangeTo(array, index, length, index + string.length)
|
||||
length += insertString(array, index, string)
|
||||
return this
|
||||
}
|
||||
|
||||
// TODO: optimize those!
|
||||
fun insert(index: Int, value: Boolean) = insert(index, value.toString())
|
||||
fun insert(index: Int, value: Byte) = insert(index, value.toString())
|
||||
fun insert(index: Int, value: Short) = insert(index, value.toString())
|
||||
@@ -296,12 +309,21 @@ class StringBuilder private constructor (
|
||||
return this
|
||||
}
|
||||
|
||||
fun append(it: String): StringBuilder = append(it.toCharArray())
|
||||
fun append(it: String): StringBuilder {
|
||||
ensureExtraCapacity(it.length)
|
||||
length += insertString(array, length, it)
|
||||
return this
|
||||
}
|
||||
|
||||
// TODO: optimize those!
|
||||
fun append(it: Boolean) = append(it.toString())
|
||||
fun append(it: Byte) = append(it.toString())
|
||||
fun append(it: Short) = append(it.toString())
|
||||
fun append(it: Int) = append(it.toString())
|
||||
fun append(it: Int): StringBuilder {
|
||||
ensureExtraCapacity(11)
|
||||
length += insertInt(array, length, it)
|
||||
return this
|
||||
}
|
||||
fun append(it: Long) = append(it.toString())
|
||||
fun append(it: Float) = append(it.toString())
|
||||
fun append(it: Double) = append(it.toString())
|
||||
|
||||
Reference in New Issue
Block a user