improve performance by using std::string_view instead of std::string

This commit is contained in:
EricPlayZ
2025-02-25 02:17:21 +02:00
parent e7351020a4
commit d81cac478b
8 changed files with 54 additions and 32 deletions

View File

@ -47,9 +47,9 @@ namespace EGSDK::Engine {
using Base::Find;
using Base::none_of;
std::unique_ptr<CVar>& try_emplace(std::unique_ptr<CVar> var) override;
std::unique_ptr<CVar>& AddVar(std::unique_ptr<CVar> var) override;
CVar* Find(uint32_t valueOffset) const;
void Erase(const std::string& name) override;
void Erase(std::string_view name) override;
bool none_of(uint32_t valueOffset);
private:

View File

@ -84,9 +84,9 @@ namespace EGSDK::Engine {
}
}
if (!customVar)
customVar = customVars.try_emplace(std::make_unique<VarT>(name, var->GetType())).get();
customVar = customVars.AddVar(std::make_unique<VarT>(name, var->GetType())).get();
if (!defVar) {
defVar = defaultVars.try_emplace(std::make_unique<VarT>(name, var->GetType())).get();
defVar = defaultVars.AddVar(std::make_unique<VarT>(name, var->GetType())).get();
if (auto varValue = var->GetValue<T>(); defVar && varValue)
defVar->SetValue<T>(*varValue);
}

View File

@ -5,7 +5,7 @@
#include <mutex>
#include <shared_mutex>
#include <functional>
#include <string>
#include <string_view>
#include <type_traits>
#include <EGSDK\Exports.h>
#include <EGSDK\Engine\VarBase.h>
@ -22,12 +22,12 @@ namespace EGSDK::Engine {
VarMapBase& operator=(VarMapBase&&) noexcept = default;
virtual ~VarMapBase() = default;
virtual std::unique_ptr<VarT>& try_emplace(std::unique_ptr<VarT> var);
VarT* Find(const std::string& name) const;
virtual void Erase(const std::string& name);
virtual std::unique_ptr<VarT>& AddVar(std::unique_ptr<VarT> var);
VarT* Find(std::string_view name) const;
virtual void Erase(std::string_view name);
bool empty() const;
bool none_of(const std::string& name) const;
bool none_of(std::string_view name) const;
size_t size();
void reserve(size_t count);
@ -37,9 +37,26 @@ namespace EGSDK::Engine {
for (const auto& name : varsOrdered)
func(vars.at(name), std::forward<Args>(args)...);
}
private:
struct CaseInsensitiveHash {
size_t operator()(std::string_view s) const {
size_t h = 0;
for (char c : s)
h = h * 101 + static_cast<size_t>(std::tolower(c));
return h;
}
};
struct CaseInsensitiveEqual {
bool operator()(std::string_view lhs, std::string_view rhs) const {
return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
[](unsigned char a, unsigned char b) {
return std::tolower(a) == std::tolower(b);
});
}
};
protected:
std::unordered_map<std::string, std::unique_ptr<VarT>> vars;
std::vector<std::string> varsOrdered;
std::unordered_map<std::string_view, std::unique_ptr<VarT>, CaseInsensitiveHash, CaseInsensitiveEqual> vars;
std::vector<std::string_view> varsOrdered;
mutable std::mutex writeMutex;
mutable std::shared_mutex readMutex;
};

View File

@ -87,15 +87,17 @@ namespace EGSDK::Engine {
SetType(VarType::Vec4);
}
std::unique_ptr<CVar>& CVarMap::try_emplace(std::unique_ptr<CVar> cVar) {
std::unique_ptr<CVar>& CVarMap::AddVar(std::unique_ptr<CVar> cVar) {
std::lock_guard lock(writeMutex);
const std::string& name = cVar->GetName();
const char* name = cVar->GetName();
auto [it, inserted] = vars.try_emplace(name, std::move(cVar));
if (inserted) {
varsOrdered.emplace_back(name);
varsOrdered.push_back(name);
if (uint32_t valueOffset = it->second->valueOffset.data; valueOffset || valueOffset != 0xCDCDCDCD)
varsByValueOffset[valueOffset] = it->second.get();
}
else
cVar.release();
return it->second;
}
CVar* CVarMap::Find(uint32_t valueOffset) const {
@ -103,7 +105,7 @@ namespace EGSDK::Engine {
auto it = varsByValueOffset.find(valueOffset);
return it == varsByValueOffset.end() ? nullptr : it->second;
}
void CVarMap::Erase(const std::string& name) {
void CVarMap::Erase(std::string_view name) {
std::lock_guard lock(writeMutex);
auto it = vars.find(name);
if (it == vars.end())

View File

@ -8,22 +8,24 @@ namespace EGSDK::Engine {
VarMapBase<VarT>::VarMapBase() : vars(), varsOrdered(), writeMutex(), readMutex() {}
template <typename VarT>
std::unique_ptr<VarT>& VarMapBase<VarT>::try_emplace(std::unique_ptr<VarT> var) {
std::unique_ptr<VarT>& VarMapBase<VarT>::AddVar(std::unique_ptr<VarT> var) {
std::lock_guard lock(writeMutex);
const std::string& name = var->GetName();
const char* name = var->GetName();
auto [it, inserted] = vars.try_emplace(name, std::move(var));
if (inserted)
varsOrdered.push_back(name);
else
var.release();
return it->second;
}
template <typename VarT>
VarT* VarMapBase<VarT>::Find(const std::string& name) const {
VarT* VarMapBase<VarT>::Find(std::string_view name) const {
std::shared_lock lock(readMutex);
auto it = vars.find(name);
return (it != vars.end()) ? it->second.get() : nullptr;
}
template <typename VarT>
void VarMapBase<VarT>::Erase(const std::string& name) {
void VarMapBase<VarT>::Erase(std::string_view name) {
std::lock_guard lock(writeMutex);
auto it = vars.find(name);
if (it == vars.end())
@ -40,7 +42,7 @@ namespace EGSDK::Engine {
return vars.empty();
}
template <typename VarT>
bool VarMapBase<VarT>::none_of(const std::string& name) const {
bool VarMapBase<VarT>::none_of(std::string_view name) const {
std::shared_lock lock(readMutex);
return vars.find(name) == vars.end();
}

View File

@ -85,15 +85,15 @@ namespace EGSDK::GamePH {
if (!playerVar) {
if constexpr (std::is_same_v<T, std::string>) {
auto stringPlayerVar = std::make_unique<StringPlayerVariable>(name);
defaultVars.try_emplace(std::move(stringPlayerVar));
defaultVars.AddVar(std::move(stringPlayerVar));
} else if constexpr (std::is_same_v<T, float>) {
auto floatPlayerVar = std::make_unique<FloatPlayerVariable>(name);
floatPlayerVar->SetValue(value);
defaultVars.try_emplace(std::move(floatPlayerVar));
defaultVars.AddVar(std::move(floatPlayerVar));
} else if constexpr (std::is_same_v<T, bool>) {
auto boolPlayerVar = std::make_unique<BoolPlayerVariable>(name);
boolPlayerVar->SetValue(value);
defaultVars.try_emplace(std::move(boolPlayerVar));
defaultVars.AddVar(std::move(boolPlayerVar));
}
} else {
if constexpr (std::is_same_v<T, std::string>) {
@ -319,16 +319,16 @@ namespace EGSDK::GamePH {
Engine::VarType playerVarType = getPlayerVarType(funcAddress, startOfFunc);
switch (playerVarType) {
case Engine::VarType::String:
vars.try_emplace(std::make_unique<StringPlayerVariable>(playerVarName));
vars.AddVar(std::make_unique<StringPlayerVariable>(playerVarName));
break;
case Engine::VarType::Float:
vars.try_emplace(std::make_unique<FloatPlayerVariable>(playerVarName));
vars.AddVar(std::make_unique<FloatPlayerVariable>(playerVarName));
break;
case Engine::VarType::Bool:
vars.try_emplace(std::make_unique<BoolPlayerVariable>(playerVarName));
vars.AddVar(std::make_unique<BoolPlayerVariable>(playerVarName));
break;
default:
//vars.try_emplace(std::make_unique<PlayerVar>(playerVarName));
//vars.AddVar(std::make_unique<PlayerVar>(playerVarName));
break;
}
}

View File

@ -282,28 +282,28 @@ namespace EGT::Engine {
{
cVarPtr->SetName(name);
cVarPtr->SetType(EGSDK::Engine::VarType::Float);
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
EGSDK::Engine::CVars::vars.AddVar(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
break;
}
case 0x198:
{
cVarPtr->SetName(name);
cVarPtr->SetType(EGSDK::Engine::VarType::Int);
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
EGSDK::Engine::CVars::vars.AddVar(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
break;
}
case 0x1C8:
{
cVarPtr->SetName(name);
cVarPtr->SetType(EGSDK::Engine::VarType::Vec3);
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
EGSDK::Engine::CVars::vars.AddVar(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
break;
}
case 0x1D8:
{
cVarPtr->SetName(name);
cVarPtr->SetType(EGSDK::Engine::VarType::Vec4);
EGSDK::Engine::CVars::vars.try_emplace(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
EGSDK::Engine::CVars::vars.AddVar(std::unique_ptr<EGSDK::Engine::CVar>(cVarPtr));
break;
}
default:

View File

@ -282,7 +282,8 @@ namespace EGT::Menu {
lensDistortionJustEnabled = false;
}
EGSDK::GamePH::PlayerVariables::GetVarRef("FOVCorrection")->SetValue(goProMode.GetValue() ? (altLensDistortion / 100.0f) : (lensDistortion / 100.0f));
if (auto fovCorrectionVar = EGSDK::GamePH::PlayerVariables::GetVarRef("FOVCorrection"))
fovCorrectionVar->SetValue(goProMode.GetValue() ? (altLensDistortion / 100.0f) : (lensDistortion / 100.0f));
EGSDK::GamePH::PlayerVariables::ManageVarByBool("SprintHeadCorrectionFactor", 0.0f, baseSprintHeadCorrectionFactor, goProMode.GetValue() ? goProMode.GetValue() : disableHeadCorrection.GetValue(), true);
}
static void UpdateDisabledOptions() {