Optimize important case of string appending to the builder. (#1591)

This commit is contained in:
Nikolay Igotti
2018-05-15 16:00:36 +03:00
committed by GitHub
parent 7fe6d44231
commit dff4ce98e9
2 changed files with 49 additions and 3 deletions
+24
View File
@@ -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())