Skip to content

Commit

Permalink
Strings: Avoid unnecessary std::string allocation churn in sorters
Browse files Browse the repository at this point in the history
  • Loading branch information
JGRennison committed Oct 26, 2024
1 parent 63345b2 commit abd69a9
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 23 deletions.
8 changes: 5 additions & 3 deletions src/build_vehicle_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,18 +275,20 @@ static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
*/
static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem &b, const GUIEngineListSortCache &cache)
{
static std::string last_name[2] = { {}, {} };
static format_buffer last_name[2] = { {}, {} };

if (a.engine_id != _last_engine[0]) {
_last_engine[0] = a.engine_id;
SetDParam(0, PackEngineNameDParam(a.engine_id, EngineNameContext::PurchaseList));
last_name[0] = GetString(STR_ENGINE_NAME);
last_name[0].clear();
AppendStringInPlace(last_name[0], STR_ENGINE_NAME);
}

if (b.engine_id != _last_engine[1]) {
_last_engine[1] = b.engine_id;
SetDParam(0, PackEngineNameDParam(b.engine_id, EngineNameContext::PurchaseList));
last_name[1] = GetString(STR_ENGINE_NAME);
last_name[1].clear();
AppendStringInPlace(last_name[1], STR_ENGINE_NAME);
}

int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
Expand Down
7 changes: 5 additions & 2 deletions src/cargotype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "stdafx.h"
#include "cargotype.h"
#include "core/format.hpp"
#include "core/geometry_func.hpp"
#include "gfx_func.h"
#include "newgrf_cargo.h"
Expand Down Expand Up @@ -199,8 +200,10 @@ std::span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo s
/** Sort cargo specifications by their name. */
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
{
std::string a_name = GetString(a->name);
std::string b_name = GetString(b->name);
format_buffer a_name;
format_buffer b_name;
AppendStringInPlace(a_name, a->name);
AppendStringInPlace(b_name, b->name);

int res = StrNaturalCompare(a_name, b_name); // Sort by name (natural sorting).

Expand Down
8 changes: 6 additions & 2 deletions src/core/format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ struct format_buffer_base : public format_to_buffer {
* Includes convenience wrappers to access the buffer.
* Can be used as a fmt argument.
*/
struct format_buffer final : public format_buffer_base<fmt::inline_buffer_size> {};
struct format_buffer final : public format_buffer_base<fmt::inline_buffer_size> {
format_buffer() {}
};

/**
* format_to_buffer subtype where the fmt::memory_buffer is built-in.
Expand All @@ -236,7 +238,9 @@ struct format_buffer final : public format_buffer_base<fmt::inline_buffer_size>
* Can be used as a fmt argument.
*/
template <size_t SIZE>
struct format_buffer_sized final : public format_buffer_base<SIZE> {};
struct format_buffer_sized final : public format_buffer_base<SIZE> {
format_buffer_sized() {}
};

template <typename T>
struct format_by_string_view_cast : public fmt::formatter<std::string_view> {
Expand Down
29 changes: 16 additions & 13 deletions src/group_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,19 @@ void BuildGuiGroupList(GUIGroupList &dst, bool fold, Owner owner, VehicleType ve
list.ForceResort();

/* Sort the groups by their name */
std::array<std::pair<const Group *, std::string>, 2> last_group{};
std::array<std::pair<const Group *, format_buffer>, 2> last_group{};

list.Sort([&last_group](const GUIGroupListItem &a, const GUIGroupListItem &b) -> bool {
if (a.group != last_group[0].first) {
SetDParam(0, a.group->index);
last_group[0] = {a.group, GetString(STR_GROUP_NAME)};
}

if (b.group != last_group[1].first) {
SetDParam(0, b.group->index);
last_group[1] = {b.group, GetString(STR_GROUP_NAME)};
}
auto process_group = [&](size_t index, const Group *group) {
if (group != last_group[index].first) {
last_group[index].first = group;
last_group[index].second.clear();
SetDParam(0, group->index);
AppendStringInPlace(last_group[index].second, STR_GROUP_NAME);
}
};
process_group(0, a.group);
process_group(1, b.group);

int r = StrNaturalCompare(last_group[0].second, last_group[1].second); // Sort by name (natural sorting).
if (r == 0) return a.group->number < b.group->number;
Expand All @@ -197,18 +198,20 @@ void SortGUIGroupOnlyList(GUIGroupOnlyList &list)
{
/* Sort the groups by their name */
const Group *last_group[2] = { nullptr, nullptr };
std::string last_name[2] = { {}, {} };
format_buffer last_name[2] = { {}, {} };
list.Sort([&](const Group * const &a, const Group * const &b) {
if (a != last_group[0]) {
last_group[0] = a;
SetDParam(0, a->index | GROUP_NAME_HIERARCHY);
last_name[0] = GetString(STR_GROUP_NAME);
last_name[0].clear();
AppendStringInPlace(last_name[0], STR_GROUP_NAME);
}

if (b != last_group[1]) {
last_group[1] = b;
SetDParam(0, b->index | GROUP_NAME_HIERARCHY);
last_name[1] = GetString(STR_GROUP_NAME);
last_name[1].clear();
AppendStringInPlace(last_name[1], STR_GROUP_NAME);
}

int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
Expand Down
8 changes: 5 additions & 3 deletions src/vehicle_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1624,18 +1624,20 @@ static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const
/** Sort vehicles by their name */
static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b)
{
static std::string last_name[2] = { {}, {} };
static format_buffer last_name[2] = { {}, {} };

if (a != _last_vehicle[0]) {
_last_vehicle[0] = a;
SetDParam(0, a->index);
last_name[0] = GetString(STR_VEHICLE_NAME);
last_name[0].clear();
AppendStringInPlace(last_name[0], STR_VEHICLE_NAME);
}

if (b != _last_vehicle[1]) {
_last_vehicle[1] = b;
SetDParam(0, b->index);
last_name[1] = GetString(STR_VEHICLE_NAME);
last_name[1].clear();
AppendStringInPlace(last_name[1], STR_VEHICLE_NAME);
}

int r = StrNaturalCompare(last_name[0], last_name[1]); // Sort by name (natural sorting).
Expand Down

0 comments on commit abd69a9

Please sign in to comment.