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());
|
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) {
|
KBoolean Kotlin_String_equals(KString thiz, KConstRef other) {
|
||||||
if (other == nullptr || other->type_info() != theStringTypeInfo) return false;
|
if (other == nullptr || other->type_info() != theStringTypeInfo) return false;
|
||||||
// Important, due to literal internalization.
|
// Important, due to literal internalization.
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ private external fun String.toUtf8OrThrowImpl(start: Int, size: Int) : ByteArray
|
|||||||
@SymbolName("Kotlin_String_fromCharArray")
|
@SymbolName("Kotlin_String_fromCharArray")
|
||||||
external fun fromCharArray(array: CharArray, start: Int, size: Int) : String
|
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]
|
* Builds new string by populating newly created [StringBuilder] using provided [builderAction]
|
||||||
* and then converting it to [String].
|
* and then converting it to [String].
|
||||||
@@ -253,8 +259,15 @@ class StringBuilder private constructor (
|
|||||||
return this
|
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: Boolean) = insert(index, value.toString())
|
||||||
fun insert(index: Int, value: Byte) = insert(index, value.toString())
|
fun insert(index: Int, value: Byte) = insert(index, value.toString())
|
||||||
fun insert(index: Int, value: Short) = insert(index, value.toString())
|
fun insert(index: Int, value: Short) = insert(index, value.toString())
|
||||||
@@ -296,12 +309,21 @@ class StringBuilder private constructor (
|
|||||||
return this
|
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: Boolean) = append(it.toString())
|
||||||
fun append(it: Byte) = append(it.toString())
|
fun append(it: Byte) = append(it.toString())
|
||||||
fun append(it: Short) = 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: Long) = append(it.toString())
|
||||||
fun append(it: Float) = append(it.toString())
|
fun append(it: Float) = append(it.toString())
|
||||||
fun append(it: Double) = append(it.toString())
|
fun append(it: Double) = append(it.toString())
|
||||||
|
|||||||
Reference in New Issue
Block a user