From b33abd2761b5d9253840cc5a722ad6ae25ec21f4 Mon Sep 17 00:00:00 2001 From: Egor Gavrilov <55379903+che6a@users.noreply.github.com> Date: Tue, 12 Sep 2023 02:58:32 +0500 Subject: [PATCH] perf(skymp5-server): replace stringstream with standard C I/O functions (#1672) --- .../cpp/server_guest_lib/FormDesc.cpp | 51 ++++++++++++++----- skymp5-server/cpp/server_guest_lib/FormDesc.h | 2 +- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/skymp5-server/cpp/server_guest_lib/FormDesc.cpp b/skymp5-server/cpp/server_guest_lib/FormDesc.cpp index ae7e3d2f7a..3bf295b3dd 100644 --- a/skymp5-server/cpp/server_guest_lib/FormDesc.cpp +++ b/skymp5-server/cpp/server_guest_lib/FormDesc.cpp @@ -1,24 +1,44 @@ #include "FormDesc.h" -#include +#include std::string FormDesc::ToString(char delimiter) const { - std::stringstream ss; - ss << std::hex << shortFormId; - if (!file.empty()) - ss << delimiter << file; - return ss.str(); + auto fullFmt = "%0x%c%s"; + auto idFmt = "%0x"; + size_t size = !file.empty() + ? std::snprintf(nullptr, 0, fullFmt, shortFormId, delimiter, file.c_str()) + : std::snprintf(nullptr, 0, idFmt, shortFormId); + + std::string buffer; + buffer.resize(size); + + if (!file.empty()) { + std::sprintf(buffer.data(), fullFmt, shortFormId, delimiter, file.c_str()); + } else { + std::sprintf(buffer.data(), idFmt, shortFormId); + } + return buffer; } FormDesc FormDesc::FromString(std::string str, char delimiter) { - for (auto& ch : str) - if (ch == delimiter) - ch = ' '; - - std::istringstream ss(str); FormDesc res; - ss >> std::hex >> res.shortFormId >> res.file; + std::string id, file; + + if (str.find(delimiter) == std::string::npos) { + std::sscanf(str.data(), "%x", &res.shortFormId); + return res; + } + + for (auto it = str.begin(); it != str.end(); ++it) { + if (*it == delimiter) { + id = { str.begin(), it }; + res.file = { it + 1, str.end() }; + break; + } + } + + std::sscanf(id.data(), "%x", &res.shortFormId); return res; } @@ -75,3 +95,10 @@ FormDesc FormDesc::FromFormId(uint32_t formId, } return res; } + +static const FormDesc kTamriel = FormDesc::FromString("3c:Skyrim.esm"); + +FormDesc FormDesc::Tamriel() +{ + return kTamriel; +} diff --git a/skymp5-server/cpp/server_guest_lib/FormDesc.h b/skymp5-server/cpp/server_guest_lib/FormDesc.h index ac0175596e..e02dac7a8b 100644 --- a/skymp5-server/cpp/server_guest_lib/FormDesc.h +++ b/skymp5-server/cpp/server_guest_lib/FormDesc.h @@ -39,7 +39,7 @@ class FormDesc std::make_tuple(right.shortFormId, right.file); } - static FormDesc Tamriel() { return FromString("3c:Skyrim.esm"); } + static FormDesc Tamriel(); uint32_t shortFormId = 0; std::string file;