Skip to content

Commit

Permalink
Merge pull request #100024 from Ivorforce/optimize-string-single-char
Browse files Browse the repository at this point in the history
Optimize string single char contains calls.
  • Loading branch information
Repiteo committed Dec 9, 2024
2 parents 101b78f + b5c31eb commit a607bca
Show file tree
Hide file tree
Showing 61 changed files with 108 additions and 99 deletions.
2 changes: 1 addition & 1 deletion core/debugger/remote_debugger_peer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
String debug_host = p_uri.replace("tcp://", "");
uint16_t debug_port = 6007;

if (debug_host.contains(":")) {
if (debug_host.contains_char(':')) {
int sep_pos = debug_host.rfind_char(':');
debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos);
Expand Down
2 changes: 1 addition & 1 deletion core/extension/extension_api_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,7 @@ Dictionary GDExtensionAPIDump::generate_extension_api(bool p_include_docs) {
if (F.name.begins_with("_")) {
continue; //hidden property
}
if (F.name.contains("/")) {
if (F.name.contains_char('/')) {
// Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion core/io/file_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ bool FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_
for (int i = 0; i < size; ++i) {
String value = p_values[i];

if (value.contains("\"") || value.contains(p_delim) || value.contains("\n")) {
if (value.contains_char('"') || value.contains(p_delim) || value.contains_char('\n')) {
value = "\"" + value.replace("\"", "\"\"") + "\"";
}
if (i < size - 1) {
Expand Down
4 changes: 2 additions & 2 deletions core/io/file_access_pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
// Search for directory.
PackedDir *cd = root;

if (simplified_path.contains("/")) { // In a subdirectory.
if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/");

for (int j = 0; j < ds.size(); j++) {
Expand Down Expand Up @@ -104,7 +104,7 @@ void PackedData::remove_path(const String &p_path) {
// Search for directory.
PackedDir *cd = root;

if (simplified_path.contains("/")) { // In a subdirectory.
if (simplified_path.contains_char('/')) { // In a subdirectory.
Vector<String> ds = simplified_path.get_base_dir().split("/");

for (int j = 0; j < ds.size(); j++) {
Expand Down
2 changes: 1 addition & 1 deletion core/io/ip_address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ IPAddress::IPAddress(const String &p_string) {
// Wildcard (not a valid IP)
wildcard = true;

} else if (p_string.contains(":")) {
} else if (p_string.contains_char(':')) {
// IPv6
_parse_ipv6(p_string);
valid = true;
Expand Down
2 changes: 1 addition & 1 deletion core/object/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName

String enum_name = p_enum;
if (!enum_name.is_empty()) {
if (enum_name.contains(".")) {
if (enum_name.contains_char('.')) {
enum_name = enum_name.get_slicec('.', 1);
}

Expand Down
10 changes: 9 additions & 1 deletion core/string/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3314,6 +3314,10 @@ int String::find(const String &p_str, int p_from) const {
return -1; // won't find anything!
}

if (src_len == 1) {
return find_char(p_str[0], p_from); // Optimize with single-char find.
}

const char32_t *src = get_data();
const char32_t *str = p_str.get_data();

Expand Down Expand Up @@ -3354,6 +3358,10 @@ int String::find(const char *p_str, int p_from) const {
return -1; // won't find anything!
}

if (src_len == 1) {
return find_char(*p_str, p_from); // Optimize with single-char find.
}

const char32_t *src = get_data();

if (src_len == 1) {
Expand Down Expand Up @@ -4081,7 +4089,7 @@ String String::format(const Variant &values, const String &placeholder) const {
Variant v_val = values_arr[i];
String val = v_val;

if (placeholder.contains("_")) {
if (placeholder.contains_char('_')) {
new_string = new_string.replace(placeholder.replace("_", i_as_str), val);
} else {
new_string = new_string.replace_first(placeholder, val);
Expand Down
1 change: 1 addition & 0 deletions core/string/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ class String {
_FORCE_INLINE_ bool is_empty() const { return length() == 0; }
_FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; }
_FORCE_INLINE_ bool contains_char(char32_t p_chr) const { return find_char(p_chr) != -1; }
_FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; }
_FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; }

Expand Down
2 changes: 1 addition & 1 deletion core/variant/variant_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1961,7 +1961,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::FLOAT: {
String s = rtos_fix(p_variant.operator double());
if (s != "inf" && s != "inf_neg" && s != "nan") {
if (!s.contains(".") && !s.contains("e")) {
if (!s.contains_char('.') && !s.contains_char('e')) {
s += ".0";
}
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/unix/os_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,13 +949,13 @@ String OS_Unix::get_environment(const String &p_var) const {
}

void OS_Unix::set_environment(const String &p_var, const String &p_value) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1);
ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var));
}

void OS_Unix::unset_environment(const String &p_var) const {
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains_char('='), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
unsetenv(p_var.utf8().get_data());
}

Expand Down
2 changes: 1 addition & 1 deletion editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ void ConnectDialog::set_dst_node(Node *p_node) {

StringName ConnectDialog::get_dst_method_name() const {
String txt = dst_method->get_text();
if (txt.contains("(")) {
if (txt.contains_char('(')) {
txt = txt.left(txt.find_char('(')).strip_edges();
}
return txt;
Expand Down
2 changes: 1 addition & 1 deletion editor/debugger/debug_adapter/debug_adapter_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ Dictionary DebugAdapterParser::req_setBreakpoints(const Dictionary &p_params) co
}

// If path contains \, it's a Windows path, so we need to convert it to /, and make the drive letter uppercase
if (source.path.contains("\\")) {
if (source.path.contains_char('\\')) {
source.path = source.path.replace("\\", "/");
source.path = source.path.substr(0, 1).to_upper() + source.path.substr(1);
}
Expand Down
2 changes: 1 addition & 1 deletion editor/debugger/debug_adapter/debug_adapter_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class DebugAdapterParser : public Object {

_FORCE_INLINE_ bool is_valid_path(const String &p_path) const {
// If path contains \, it's a Windows path, so we need to convert it to /, and check as case-insensitive.
if (p_path.contains("\\")) {
if (p_path.contains_char('\\')) {
String project_path = ProjectSettings::get_singleton()->get_resource_path();
String path = p_path.replace("\\", "/");
return path.containsn(project_path);
Expand Down
6 changes: 3 additions & 3 deletions editor/directory_create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ String DirectoryCreateDialog::_validate_path(const String &p_path) const {
return TTR("Folder name cannot be empty.");
}
}
if (part.contains("\\") || part.contains(":") || part.contains("*") ||
part.contains("|") || part.contains(">") || part.ends_with(".") || part.ends_with(" ")) {
if (part.contains_char('\\') || part.contains_char(':') || part.contains_char('*') ||
part.contains_char('|') || part.contains_char('>') || part.ends_with(".") || part.ends_with(" ")) {
if (is_file) {
return TTR("File name contains invalid characters.");
} else {
Expand Down Expand Up @@ -101,7 +101,7 @@ void DirectoryCreateDialog::_on_dir_path_changed() {
const String error = _validate_path(path);

if (error.is_empty()) {
if (path.contains("/")) {
if (path.contains_char('/')) {
if (mode == MODE_DIRECTORY) {
validation_panel->set_message(EditorValidationPanel::MSG_ID_DEFAULT, TTR("Using slashes in folder names will create subfolders recursively."), EditorValidationPanel::MSG_OK);
} else {
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_feature_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ void EditorFeatureProfileManager::_erase_selected_profile() {

void EditorFeatureProfileManager::_create_new_profile() {
String name = new_profile_name->get_text().strip_edges();
if (!name.is_valid_filename() || name.contains(".")) {
if (!name.is_valid_filename() || name.contains_char('.')) {
EditorNode::get_singleton()->show_warning(TTR("Profile must be a valid filename and must not contain '.'"));
return;
}
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ void EditorFileSystem::_scan_filesystem() {

FileCache fc;
fc.type = split[1];
if (fc.type.contains("/")) {
if (fc.type.contains_char('/')) {
fc.type = split[1].get_slice("/", 0);
fc.resource_script_class = split[1].get_slice("/", 1);
}
Expand Down
8 changes: 4 additions & 4 deletions editor/editor_help.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void EditorHelp::_class_desc_select(const String &p_select) {
}
}

if (link.contains(".")) {
if (link.contains_char('.')) {
const int class_end = link.find_char('.');
emit_signal(SNAME("go_to_help"), topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
}
Expand Down Expand Up @@ -365,7 +365,7 @@ static void _add_type_to_rt(const String &p_type, const String &p_enum, bool p_i

bool is_enum_type = !p_enum.is_empty();
bool is_bitfield = p_is_bitfield && is_enum_type;
bool can_ref = !p_type.contains("*") || is_enum_type;
bool can_ref = !p_type.contains_char('*') || is_enum_type;

String link_t = p_type; // For links in metadata
String display_t; // For display purposes.
Expand Down Expand Up @@ -2552,7 +2552,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt, const C
p_rt->push_meta("@" + link_tag + " " + link_target, underline_mode);

if (link_tag == "member" &&
((!link_target.contains(".") && (p_class == "ProjectSettings" || p_class == "EditorSettings")) ||
((!link_target.contains_char('.') && (p_class == "ProjectSettings" || p_class == "EditorSettings")) ||
link_target.begins_with("ProjectSettings.") || link_target.begins_with("EditorSettings."))) {
// Special formatting for both ProjectSettings and EditorSettings.
String prefix;
Expand Down Expand Up @@ -3665,7 +3665,7 @@ void EditorHelpBit::_meta_clicked(const String &p_select) {
return;
}

if (link.contains(".")) {
if (link.contains_char('.')) {
const int class_end = link.find_char('.');
_go_to_help(topic + ":" + link.left(class_end) + ":" + link.substr(class_end + 1));
} else {
Expand Down
6 changes: 3 additions & 3 deletions editor/editor_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ void EditorProperty::_notification(int p_what) {
} else {
color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color"));
}
if (label.contains(".")) {
if (label.contains_char('.')) {
// FIXME: Move this to the project settings editor, as this is only used
// for project settings feature tag overrides.
color.a = 0.5;
Expand Down Expand Up @@ -3177,7 +3177,7 @@ void EditorInspector::update_tree() {
}

// Get the property label's string.
String name_override = (path.contains("/")) ? path.substr(path.rfind_char('/') + 1) : path;
String name_override = (path.contains_char('/')) ? path.substr(path.rfind_char('/') + 1) : path;
String feature_tag;
{
const int dot = name_override.find_char('.');
Expand Down Expand Up @@ -3326,7 +3326,7 @@ void EditorInspector::update_tree() {
array_element_prefix = class_name_components[0];
editor_inspector_array = memnew(EditorInspectorArray(all_read_only));

String array_label = path.contains("/") ? path.substr(path.rfind_char('/') + 1) : path;
String array_label = path.contains_char('/') ? path.substr(path.rfind_char('/') + 1) : path;
array_label = EditorPropertyNameProcessor::get_singleton()->process_name(property_label_string, property_name_style, p.name, doc_name);
int page = per_array_page.has(array_element_prefix) ? per_array_page[array_element_prefix] : 0;
editor_inspector_array->setup_with_move_element_function(object, array_label, array_element_prefix, page, c, use_folding);
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ void EditorPropertyLayersGrid::_rename_operation_confirm() {
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
return;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
} else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
return;
}
Expand Down Expand Up @@ -2873,7 +2873,7 @@ void EditorPropertyNodePath::update_property() {
const Node *target_node = base_node->get_node(p);
ERR_FAIL_NULL(target_node);

if (String(target_node->get_name()).contains("@")) {
if (String(target_node->get_name()).contains_char('@')) {
assign->set_button_icon(Ref<Texture2D>());
assign->set_text(p);
return;
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_sectioned_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class SectionedInspectorFilter : public Object {

if (pi.name.begins_with(section + "/")) {
pi.name = pi.name.replace_first(section + "/", "");
if (!allow_sub && pi.name.contains("/")) {
if (!allow_sub && pi.name.contains_char('/')) {
continue;
}
p_list->push_back(pi);
Expand Down Expand Up @@ -247,7 +247,7 @@ void SectionedInspector::update_category_list() {
continue;
}

if (pi.name.contains(":") || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
if (pi.name.contains_char(':') || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
continue;
}

Expand Down
4 changes: 2 additions & 2 deletions editor/filesystem_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,7 @@ void FileSystemDock::_rename_operation_confirm() {
if (new_name.length() == 0) {
EditorNode::get_singleton()->show_warning(TTR("No name provided."));
rename_error = true;
} else if (new_name.contains("/") || new_name.contains("\\") || new_name.contains(":")) {
} else if (new_name.contains_char('/') || new_name.contains_char('\\') || new_name.contains_char(':')) {
EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
rename_error = true;
} else if (new_name[0] == '.') {
Expand Down Expand Up @@ -2266,7 +2266,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
test_args.push_back("command -v " + terminal_emulator);
const Error err = OS::get_singleton()->execute("bash", test_args, &pipe);
// Check if a path to the terminal executable exists.
if (err == OK && pipe.contains("/")) {
if (err == OK && pipe.contains_char('/')) {
chosen_terminal_emulator = terminal_emulator;
break;
} else if (err == ERR_CANT_FORK) {
Expand Down
2 changes: 1 addition & 1 deletion editor/gui/scene_tree_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ bool SceneTreeEditor::_item_matches_all_terms(TreeItem *p_item, const PackedStri
const String &term = p_terms[i];

// Recognize special filter.
if (term.contains(":") && !term.get_slicec(':', 0).is_empty()) {
if (term.contains_char(':') && !term.get_slicec(':', 0).is_empty()) {
String parameter = term.get_slicec(':', 0);
String argument = term.get_slicec(':', 1);

Expand Down
4 changes: 2 additions & 2 deletions editor/import/3d/collada.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1808,10 +1808,10 @@ void Collada::_parse_animation(XMLParser &p_parser) {
}
}

if (target.contains("/")) { //transform component
if (target.contains_char('/')) { //transform component
track.target = target.get_slicec('/', 0);
track.param = target.get_slicec('/', 1);
if (track.param.contains(".")) {
if (track.param.contains_char('.')) {
track.component = track.param.get_slice(".", 1).to_upper();
}
track.param = track.param.get_slice(".", 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
List<StringName> anims;
ap->get_animation_list(&anims);
for (const StringName &name : anims) {
if (String(name).contains("/")) {
if (String(name).contains_char('/')) {
continue; // Avoid animation library which may be created by importer dynamically.
}

Expand Down
2 changes: 1 addition & 1 deletion editor/plugins/animation_blend_tree_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima

const String &new_name = p_text;

ERR_FAIL_COND(new_name.is_empty() || new_name.contains(".") || new_name.contains("/"));
ERR_FAIL_COND(new_name.is_empty() || new_name.contains_char('.') || new_name.contains_char('/'));

if (new_name == prev_name) {
return; //nothing to do
Expand Down
2 changes: 1 addition & 1 deletion editor/plugins/animation_library_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ void AnimationLibraryEditor::_item_renamed() {
bool restore_text = false;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();

if (String(text).contains("/") || String(text).contains(":") || String(text).contains(",") || String(text).contains("[")) {
if (String(text).contains_char('/') || String(text).contains_char(':') || String(text).contains_char(',') || String(text).contains_char('[')) {
restore_text = true;
} else {
if (ti->get_parent() == tree->get_root()) {
Expand Down
8 changes: 4 additions & 4 deletions editor/plugins/animation_player_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ void AnimationPlayerEditor::_animation_rename() {
String selected_name = animation->get_item_text(selected);

// Remove library prefix if present.
if (selected_name.contains("/")) {
if (selected_name.contains_char('/')) {
selected_name = selected_name.get_slice("/", 1);
}

Expand Down Expand Up @@ -537,7 +537,7 @@ void AnimationPlayerEditor::_animation_remove_confirmed() {
ERR_FAIL_COND(al.is_null());

// For names of form lib_name/anim_name, remove library name prefix.
if (current.contains("/")) {
if (current.contains_char('/')) {
current = current.get_slice("/", 1);
}
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
Expand Down Expand Up @@ -626,7 +626,7 @@ void AnimationPlayerEditor::_animation_name_edited() {

// Extract library prefix if present.
String new_library_prefix = "";
if (current.contains("/")) {
if (current.contains_char('/')) {
new_library_prefix = current.get_slice("/", 0) + "/";
current = current.get_slice("/", 1);
}
Expand Down Expand Up @@ -1340,7 +1340,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
break;
}

if (new_name.contains("/")) {
if (new_name.contains_char('/')) {
// Discard library prefix.
new_name = new_name.get_slice("/", 1);
}
Expand Down
Loading

0 comments on commit a607bca

Please sign in to comment.