Quellcode durchsuchen

Change String copy_from_unchecked to actually not check the string, leading to performance optimizations across substr, count, and StringBuilder.

Lukas Tenbrink vor 8 Monaten
Ursprung
Commit
541e721cac
1 geänderte Dateien mit 25 neuen und 20 gelöschten Zeilen
  1. 25 20
      core/string/ustring.cpp

+ 25 - 20
core/string/ustring.cpp

@@ -324,7 +324,27 @@ void String::parse_utf32(const Span<char32_t> &p_cstr) {
 		return;
 	}
 
-	copy_from_unchecked(p_cstr.ptr(), p_cstr.size());
+	resize(p_cstr.size() + 1);
+	const char32_t *src = p_cstr.ptr();
+	const char32_t *end = p_cstr.ptr() + p_cstr.size();
+	char32_t *dst = ptrw();
+
+	// Copy the string, and check for UTF-32 problems.
+	for (; src < end; ++src, ++dst) {
+		const char32_t chr = *src;
+		if ((chr & 0xfffff800) == 0xd800) {
+			print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)chr), true);
+			*dst = _replacement_char;
+			continue;
+		}
+		if (chr > 0x10ffff) {
+			print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)chr), true);
+			*dst = _replacement_char;
+			continue;
+		}
+		*dst = chr;
+	}
+	*dst = 0;
 }
 
 void String::parse_utf32(const char32_t &p_char) {
@@ -354,27 +374,12 @@ void String::parse_utf32(const char32_t &p_char) {
 // p_char != nullptr
 // p_length > 0
 // p_length <= p_char strlen
+// p_char is a valid UTF32 string
 void String::copy_from_unchecked(const char32_t *p_char, const int p_length) {
-	resize(p_length + 1);
-
-	const char32_t *end = p_char + p_length;
+	resize(p_length + 1); // + 1 for \0
 	char32_t *dst = ptrw();
-
-	for (; p_char < end; ++p_char, ++dst) {
-		const char32_t chr = *p_char;
-		if ((chr & 0xfffff800) == 0xd800) {
-			print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)chr));
-			*dst = _replacement_char;
-			continue;
-		}
-		if (chr > 0x10ffff) {
-			print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)chr));
-			*dst = _replacement_char;
-			continue;
-		}
-		*dst = chr;
-	}
-	*dst = 0;
+	memcpy(dst, p_char, p_length * sizeof(char32_t));
+	*(dst + p_length) = _null;
 }
 
 String String::operator+(const String &p_str) const {