Browse Source

Optimize _camelcase_to_underscore (and thus String.capitalize) by using a rolling cache of character attributes, instead of re-computing each iteration.

Lukas Tenbrink 8 months ago
parent
commit
8d82933c7c
1 changed files with 16 additions and 8 deletions
  1. 16 8
      core/string/ustring.cpp

+ 16 - 8
core/string/ustring.cpp

@@ -1109,17 +1109,21 @@ String String::_camelcase_to_underscore() const {
 	String new_string;
 	String new_string;
 	int start_index = 0;
 	int start_index = 0;
 
 
-	for (int i = 1; i < size(); i++) {
-		bool is_prev_upper = is_unicode_upper_case(cstr[i - 1]);
-		bool is_prev_lower = is_unicode_lower_case(cstr[i - 1]);
-		bool is_prev_digit = is_digit(cstr[i - 1]);
+	if (length() == 0) {
+		return *this;
+	}
 
 
-		bool is_curr_upper = is_unicode_upper_case(cstr[i]);
-		bool is_curr_lower = is_unicode_lower_case(cstr[i]);
-		bool is_curr_digit = is_digit(cstr[i]);
+	bool is_prev_upper = is_unicode_upper_case(cstr[0]);
+	bool is_prev_lower = is_unicode_lower_case(cstr[0]);
+	bool is_prev_digit = is_digit(cstr[0]);
+
+	for (int i = 1; i < length(); i++) {
+		const bool is_curr_upper = is_unicode_upper_case(cstr[i]);
+		const bool is_curr_lower = is_unicode_lower_case(cstr[i]);
+		const bool is_curr_digit = is_digit(cstr[i]);
 
 
 		bool is_next_lower = false;
 		bool is_next_lower = false;
-		if (i + 1 < size()) {
+		if (i + 1 < length()) {
 			is_next_lower = is_unicode_lower_case(cstr[i + 1]);
 			is_next_lower = is_unicode_lower_case(cstr[i + 1]);
 		}
 		}
 
 
@@ -1132,6 +1136,10 @@ String String::_camelcase_to_underscore() const {
 			new_string += substr(start_index, i - start_index) + "_";
 			new_string += substr(start_index, i - start_index) + "_";
 			start_index = i;
 			start_index = i;
 		}
 		}
+
+		is_prev_upper = is_curr_upper;
+		is_prev_lower = is_curr_lower;
+		is_prev_digit = is_curr_digit;
 	}
 	}
 
 
 	new_string += substr(start_index, size() - start_index);
 	new_string += substr(start_index, size() - start_index);