From 3e89b4a35e9294c115be24e39be7601d6e9f39d3 Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Wed, 27 Sep 2023 22:37:25 +0800 Subject: [PATCH] perf: use std::string_view --- src/MaaCore/Config/TaskData.cpp | 136 ++++++++++++++++---------------- src/MaaCore/Config/TaskData.h | 26 +++--- 2 files changed, 78 insertions(+), 84 deletions(-) diff --git a/src/MaaCore/Config/TaskData.cpp b/src/MaaCore/Config/TaskData.cpp index 978d637517..2b4add0383 100644 --- a/src/MaaCore/Config/TaskData.cpp +++ b/src/MaaCore/Config/TaskData.cpp @@ -85,81 +85,79 @@ bool asst::TaskData::parse(const json::value& json) } } - for (const std::string_view& name : m_json_all_tasks_info | views::keys) { + for (std::string_view name : m_json_all_tasks_info | views::keys) { task_status[name] = ToBeGenerate; } - auto generate_task_and_its_base = [&](const std::string& name) -> bool { - auto generate_task = [&](const std::string& name, std::string_view prefix, taskptr_t base_ptr, - const json::value& task_json) { - auto task_info_ptr = generate_task_info(name, task_json, base_ptr, prefix); - if (task_info_ptr == nullptr) { - return false; + auto generate_task = [&](std::string_view name, std::string_view prefix, taskptr_t base_ptr, + const json::value& task_json) { + auto task_info_ptr = generate_task_info(name, task_json, base_ptr, prefix); + if (task_info_ptr == nullptr) { + return false; + } + task_status[task_name_view(name)] = NotToBeGenerate; + insert_or_assign_raw_task(name, task_info_ptr); + return true; + }; + std::function generate_task_and_its_base; + generate_task_and_its_base = [&](std::string_view name, bool must_true) -> bool { + switch (task_status[task_name_view(name)]) { + case NotToBeGenerate: + // 已经显式生成 + if (m_raw_all_tasks_info.contains(name)) { + return true; } - task_status[task_name_view(name)] = NotToBeGenerate; - insert_or_assign_raw_task(name, task_info_ptr); - return true; - }; - std::function generate_fun; - generate_fun = [&](const std::string& name, bool must_true) -> bool { - switch (task_status[task_name_view(name)]) { - case NotToBeGenerate: - // 已经显式生成 - if (m_raw_all_tasks_info.contains(name)) { - return true; - } - // 隐式生成的资源 - if (size_t p = name.find('@'); p != std::string::npos) { - return generate_fun(name.substr(p + 1), must_true); - } + // 隐式生成的资源 + if (size_t p = name.find('@'); p != std::string::npos) { + return generate_task_and_its_base(name.substr(p + 1), must_true); + } - task_status[name] = NotExists; - [[fallthrough]]; - case NotExists: - if (must_true) { - // 必须有名字为 name 的资源 - Log.error("Unknown task:", name); - } - // 不一定必须有名字为 name 的资源,例如 Roguelike@Abandon 不必有 Abandon. - return false; - case ToBeGenerate: { - task_status[name] = Generating; - const json::value& task_json = m_json_all_tasks_info.at(name); + task_status[name] = NotExists; + [[fallthrough]]; + case NotExists: + if (must_true) { + // 必须有名字为 name 的资源 + Log.error("Unknown task:", name); + } + // 不一定必须有名字为 name 的资源,例如 Roguelike@Abandon 不必有 Abandon. + return false; + case ToBeGenerate: { + task_status[name] = Generating; + const json::value& task_json = m_json_all_tasks_info.at(name); - // BaseTask - if (auto opt = task_json.find("baseTask")) { - std::string base = opt.value(); - return generate_fun(base, must_true) && generate_task(name, "", get_raw(base), task_json); - } + // BaseTask + if (auto opt = task_json.find("baseTask")) { + std::string base = opt.value(); + return generate_task_and_its_base(base, must_true) && + generate_task(name, "", get_raw(base), task_json); + } - // TemplateTask - if (size_t p = name.find('@'); p != std::string::npos) { - if (std::string base = name.substr(p + 1); generate_fun(base, false)) { + // TemplateTask + if (size_t p = name.find('@'); p != std::string::npos) { + if (std::string_view base = name.substr(p + 1); generate_task_and_its_base(base, false)) { #ifdef ASST_DEBUG - if (task_json.as_object().empty() && get_raw(base)->algorithm != AlgorithmType::MatchTemplate) { - // 多余的空任务 - Log.warn("Task", name, "is a redundant empty task because it is not MatchTemplate"); - } -#endif - return generate_task(name, name.substr(0, p), get_raw(base), task_json); + if (task_json.as_object().empty() && get_raw(base)->algorithm != AlgorithmType::MatchTemplate) { + // 多余的空任务 + Log.warn("Task", name, "is a redundant empty task because it is not MatchTemplate"); } +#endif + return generate_task(name, name.substr(0, p), get_raw(base), task_json); } - return generate_task(name, "", nullptr, task_json); } - [[unlikely]] case Generating: - Log.error("Task", name, "is generated cyclically"); - return false; - [[unlikely]] default: - Log.error("Task", name, "has unknown status"); - return false; - } - }; - return generate_fun(name, true); + return generate_task(name, "", nullptr, task_json); + } + [[unlikely]] case Generating: + Log.error("Task", name, "is generated cyclically"); + return false; + [[unlikely]] default: + Log.error("Task", name, "has unknown status"); + return false; + } }; - for (const std::string_view& name : json_obj | views::keys) { - generate_task_and_its_base(std::string(name)); + for (std::string_view name : json_obj | views::keys) { + generate_task_and_its_base(name, true); } } @@ -669,7 +667,7 @@ std::optional asst::TaskData::expand_task(std::string } } -asst::TaskData::taskptr_t asst::TaskData::generate_task_info(const std::string& name, const json::value& task_json, +asst::TaskData::taskptr_t asst::TaskData::generate_task_info(std::string_view name, const json::value& task_json, taskptr_t default_ptr, std::string_view task_prefix) { if (default_ptr == nullptr) { @@ -719,7 +717,7 @@ asst::TaskData::taskptr_t asst::TaskData::generate_task_info(const std::string& return task_info_ptr; } -asst::TaskData::taskptr_t asst::TaskData::generate_match_task_info(const std::string& name, +asst::TaskData::taskptr_t asst::TaskData::generate_match_task_info(std::string_view name, const json::value& task_json, std::shared_ptr default_ptr) { @@ -728,12 +726,12 @@ asst::TaskData::taskptr_t asst::TaskData::generate_match_task_info(const std::st } auto match_task_info_ptr = std::make_shared(); #ifdef ASST_DEBUG - if (task_json.get("template", "") == name + ".png") { + if (task_json.get("template", "") == std::string(name) + ".png") { Log.warn("template name of task", name, "could be omitted."); } #endif // template 留空时不从模板任务继承 - match_task_info_ptr->templ_name = task_json.get("template", name + ".png"); + match_task_info_ptr->templ_name = task_json.get("template", std::string(name) + ".png"); m_templ_required.emplace(match_task_info_ptr->templ_name); // 其余若留空则继承模板任务 @@ -749,7 +747,7 @@ asst::TaskData::taskptr_t asst::TaskData::generate_match_task_info(const std::st return match_task_info_ptr; } -asst::TaskData::taskptr_t asst::TaskData::generate_ocr_task_info([[maybe_unused]] const std::string& name, +asst::TaskData::taskptr_t asst::TaskData::generate_ocr_task_info([[maybe_unused]] std::string_view name, const json::value& task_json, std::shared_ptr default_ptr) { @@ -780,7 +778,7 @@ asst::TaskData::taskptr_t asst::TaskData::generate_ocr_task_info([[maybe_unused] return ocr_task_info_ptr; } -asst::TaskData::taskptr_t asst::TaskData::generate_hash_task_info([[maybe_unused]] const std::string& name, +asst::TaskData::taskptr_t asst::TaskData::generate_hash_task_info([[maybe_unused]] std::string_view name, const json::value& task_json, std::shared_ptr default_ptr) { @@ -811,7 +809,7 @@ asst::TaskData::taskptr_t asst::TaskData::generate_hash_task_info([[maybe_unused return hash_task_info_ptr; } -bool asst::TaskData::append_base_task_info(taskptr_t task_info_ptr, const std::string& name, +bool asst::TaskData::append_base_task_info(taskptr_t task_info_ptr, std::string_view name, const json::value& task_json, taskptr_t default_ptr, std::string_view task_prefix) { @@ -942,7 +940,7 @@ asst::TaskData::taskptr_t asst::TaskData::_default_task_info() #ifdef ASST_DEBUG // 为了解决类似 beddc7c828126c678391e0b4da288db6d2c2d58a 导致的问题,加载的时候做一个语法检查 // 主要是处理是否包含未知键值的问题 -bool asst::TaskData::syntax_check(const std::string_view& task_name, const json::value& task_json) +bool asst::TaskData::syntax_check(std::string_view task_name, const json::value& task_json) { // clang-format off // 以下按字典序排序 diff --git a/src/MaaCore/Config/TaskData.h b/src/MaaCore/Config/TaskData.h index 47e80e9827..3b6a19b704 100644 --- a/src/MaaCore/Config/TaskData.h +++ b/src/MaaCore/Config/TaskData.h @@ -32,33 +32,33 @@ namespace asst const taskptr_t default_task_info_ptr = _default_task_info(); // 这是下面几个函数的封装 - taskptr_t generate_task_info(const std::string& name, const json::value&, taskptr_t default_ptr, + taskptr_t generate_task_info(std::string_view name, const json::value&, taskptr_t default_ptr, std::string_view task_prefix = ""); - taskptr_t generate_match_task_info(const std::string& name, const json::value&, + taskptr_t generate_match_task_info(std::string_view name, const json::value&, std::shared_ptr default_ptr); - taskptr_t generate_ocr_task_info(const std::string& name, const json::value&, + taskptr_t generate_ocr_task_info(std::string_view name, const json::value&, std::shared_ptr default_ptr); - taskptr_t generate_hash_task_info(const std::string& name, const json::value&, + taskptr_t generate_hash_task_info(std::string_view name, const json::value&, std::shared_ptr default_ptr); // TaskInfo 的基础成员 - bool append_base_task_info(taskptr_t task_info_ptr, const std::string& name, const json::value& task_json, + bool append_base_task_info(taskptr_t task_info_ptr, std::string_view name, const json::value& task_json, taskptr_t default_ptr, std::string_view task_prefix = ""); - static std::string append_prefix(const std::string& task_name, std::string_view task_prefix) + static std::string append_prefix(std::string_view task_name, std::string_view task_prefix) { if (task_prefix.ends_with('@')) [[unlikely]] { task_prefix.remove_suffix(1); } if (task_prefix.empty()) [[unlikely]] { - return task_name; + return std::string(task_name); } if (task_name.empty()) { return std::string(task_prefix); } if (task_name.starts_with('#')) { - return std::string(task_prefix) + task_name; + return std::string(task_prefix) + std::string(task_name); } - return std::string(task_prefix) + '@' + task_name; + return std::string(task_prefix) + '@' + std::string(task_name); } static tasklist_t append_prefix(const tasklist_t& base_task_list, std::string_view task_prefix_view) { @@ -83,11 +83,7 @@ namespace asst } l = r + 1; } - if (has_same_prefix) [[unlikely]] { - task_list.emplace_back(base); - continue; - } - task_list.emplace_back(append_prefix(base, task_prefix)); + task_list.emplace_back(has_same_prefix ? base : append_prefix(base, task_prefix)); } return task_list; }; @@ -146,7 +142,7 @@ namespace asst bool& task_changed, bool multi); std::optional expand_task(std::string_view name, taskptr_t old_task); #ifdef ASST_DEBUG - bool syntax_check(const std::string_view& task_name, const json::value& task_json); + bool syntax_check(std::string_view task_name, const json::value& task_json); #endif std::shared_ptr get_raw(std::string_view name) const; template