Skip to content

Commit a3c4fcd

Browse files
authored
Merge pull request #403 from OpenVicProject/optimize/construction
Optimize vector construction
2 parents d57455a + f1f06d2 commit a3c4fcd

File tree

23 files changed

+457
-126
lines changed

23 files changed

+457
-126
lines changed

src/openvic-simulation/console/ConsoleInstance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ bool ConsoleInstance::execute(std::string_view command) {
116116
}
117117
}
118118

119-
arguments.push_back(std::string_view { arg_start, arg_end });
119+
arguments.emplace_back(arg_start, arg_end);
120120

121121
// Accessing command.end() is UB
122122
if (it == command.end()) {

src/openvic-simulation/country/CountryInstance.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1832,7 +1832,10 @@ void CountryInstanceManager::update_rankings(Date today, DefineManager const& de
18321832

18331833
CountryInstanceManager::CountryInstanceManager(CountryDefinitionManager const& new_country_definition_manager)
18341834
: country_definition_manager { new_country_definition_manager },
1835-
country_definition_to_instance_map { &new_country_definition_manager.get_country_definitions() } {}
1835+
country_definition_to_instance_map { &new_country_definition_manager.get_country_definitions() } {
1836+
great_powers.reserve(16);
1837+
secondary_powers.reserve(16);
1838+
}
18361839

18371840
CountryInstance& CountryInstanceManager::get_country_instance_from_definition(CountryDefinition const& country) {
18381841
return *country_definition_to_instance_map[country];

src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ void ResourceGatheringOperation::rgo_tick() {
162162
get_country_to_report_economy_nullable->report_output(production_type, output_quantity_yesterday);
163163
}
164164

165-
market_instance.place_market_sell_order(MarketSellOrder {
165+
market_instance.place_market_sell_order({
166166
production_type.get_output_good(),
167167
output_quantity_yesterday,
168168
this,

src/openvic-simulation/economy/trading/GoodMarket.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ void GoodMarket::update_next_price_limits() {
5353
price_inverse = fixed_point_t::_1() / price;
5454
}
5555

56-
void GoodMarket::add_buy_up_to_order(GoodBuyUpToOrder const& buy_up_to_order) {
56+
void GoodMarket::add_buy_up_to_order(GoodBuyUpToOrder&& buy_up_to_order) {
5757
const std::lock_guard<std::mutex> lock_guard { *buy_lock };
58-
buy_up_to_orders.push_back(buy_up_to_order);
58+
buy_up_to_orders.push_back(std::move(buy_up_to_order));
5959
}
6060

61-
void GoodMarket::add_market_sell_order(GoodMarketSellOrder const& market_sell_order) {
61+
void GoodMarket::add_market_sell_order(GoodMarketSellOrder&& market_sell_order) {
6262
const std::lock_guard<std::mutex> lock_guard { *sell_lock };
63-
market_sell_orders.push_back(market_sell_order);
63+
market_sell_orders.push_back(std::move(market_sell_order));
6464
}
6565

6666
void GoodMarket::execute_orders(std::vector<fixed_point_t>& reusable_vector_0, std::vector<fixed_point_t>& reusable_vector_1) {

src/openvic-simulation/economy/trading/GoodMarket.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ namespace OpenVic {
4646
GoodMarket(GoodMarket&&) = default;
4747

4848
//thread safe
49-
void add_buy_up_to_order(GoodBuyUpToOrder const& buy_up_to_order);
50-
void add_market_sell_order(GoodMarketSellOrder const& market_sell_order);
49+
void add_buy_up_to_order(GoodBuyUpToOrder&& buy_up_to_order);
50+
void add_market_sell_order(GoodMarketSellOrder&& market_sell_order);
5151

5252
//not thread safe
5353
void execute_orders(std::vector<fixed_point_t>& reusable_vector_0, std::vector<fixed_point_t>& reusable_vector_1);

src/openvic-simulation/economy/trading/MarketInstance.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fixed_point_t MarketInstance::get_price_inverse(GoodDefinition const& good_defin
3131
return good_instance_manager.get_good_instance_from_definition(good_definition).get_price_inverse();
3232
}
3333

34-
void MarketInstance::place_buy_up_to_order(BuyUpToOrder const& buy_up_to_order) {
34+
void MarketInstance::place_buy_up_to_order(BuyUpToOrder&& buy_up_to_order) {
3535
GoodDefinition const& good = buy_up_to_order.get_good();
3636
if (OV_unlikely(buy_up_to_order.get_max_quantity() <= 0)) {
3737
Logger::error("Received BuyUpToOrder for ",good," with max quantity ",buy_up_to_order.get_max_quantity());
@@ -40,10 +40,10 @@ void MarketInstance::place_buy_up_to_order(BuyUpToOrder const& buy_up_to_order)
4040
}
4141

4242
GoodMarket& good_instance = good_instance_manager.get_good_instance_from_definition(good);
43-
good_instance.add_buy_up_to_order(buy_up_to_order);
43+
good_instance.add_buy_up_to_order(std::move(buy_up_to_order));
4444
}
4545

46-
void MarketInstance::place_market_sell_order(MarketSellOrder const& market_sell_order) {
46+
void MarketInstance::place_market_sell_order(MarketSellOrder&& market_sell_order) {
4747
GoodDefinition const& good = market_sell_order.get_good();
4848
if (OV_unlikely(market_sell_order.get_quantity() <= 0)) {
4949
Logger::error("Received MarketSellOrder for ", good, " with quantity ", market_sell_order.get_quantity());
@@ -60,7 +60,7 @@ void MarketInstance::place_market_sell_order(MarketSellOrder const& market_sell_
6060
}
6161

6262
GoodMarket& good_instance = good_instance_manager.get_good_instance_from_definition(good);
63-
good_instance.add_market_sell_order(market_sell_order);
63+
good_instance.add_market_sell_order(std::move(market_sell_order));
6464
}
6565

6666
void MarketInstance::execute_orders() {

src/openvic-simulation/economy/trading/MarketInstance.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ namespace OpenVic {
2929
fixed_point_t get_min_next_price(GoodDefinition const& good_definition) const;
3030
fixed_point_t get_max_money_to_allocate_to_buy_quantity(GoodDefinition const& good_definition, const fixed_point_t quantity) const;
3131
fixed_point_t get_price_inverse(GoodDefinition const& good_definition) const;
32-
void place_buy_up_to_order(BuyUpToOrder const& buy_up_to_order);
33-
void place_market_sell_order(MarketSellOrder const& market_sell_order);
32+
void place_buy_up_to_order(BuyUpToOrder&& buy_up_to_order);
33+
void place_market_sell_order(MarketSellOrder&& market_sell_order);
3434
void execute_orders();
3535
void record_price_history();
3636
};

src/openvic-simulation/history/DiplomaticHistory.cpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ std::vector<WarHistory const*> DiplomaticHistoryManager::get_wars(Date date) con
111111
bool DiplomaticHistoryManager::load_diplomacy_history_file(
112112
CountryDefinitionManager const& country_definition_manager, ast::NodeCPtr root
113113
) {
114+
// Default vanilla alliances is 2, 54 is the max I've seen in mods
115+
// Eliminates reallocations at the cost of memory usage
116+
alliances.reserve(16);
117+
// Default vanilla subjects is 42, 152 is the max I've seen in mods
118+
// Eliminates reallocations at the cost of memory usage
119+
subjects.reserve(64);
120+
// Default vanilla reparations is 0, yet to see a mod use it
121+
// Eliminates reallocations at the cost of memory usage
122+
reparations.reserve(1);
123+
114124
return expect_dictionary_keys(
115125
"alliance", ZERO_OR_MORE, [this, &country_definition_manager](ast::NodeCPtr node) -> bool {
116126
CountryDefinition const* first = nullptr;
@@ -129,7 +139,7 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(
129139
"end_date", ZERO_OR_ONE, expect_date_identifier_or_string(assign_variable_callback(end))
130140
)(node);
131141

132-
alliances.push_back({ first, second, { start, end } });
142+
alliances.emplace_back(first, second, Period { start, end });
133143
return ret;
134144
},
135145
"vassal", ZERO_OR_MORE, [this, &country_definition_manager](ast::NodeCPtr node) -> bool {
@@ -149,7 +159,7 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(
149159
"end_date", ZERO_OR_ONE, expect_date_identifier_or_string(assign_variable_callback(end))
150160
)(node);
151161

152-
subjects.push_back({ overlord, subject, SubjectHistory::type_t::VASSAL, { start, end } });
162+
subjects.emplace_back(overlord, subject, SubjectHistory::type_t::VASSAL, Period { start, end });
153163
return ret;
154164
},
155165
"union", ZERO_OR_MORE, [this, &country_definition_manager](ast::NodeCPtr node) -> bool {
@@ -169,7 +179,7 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(
169179
"end_date", ZERO_OR_ONE, expect_date_identifier_or_string(assign_variable_callback(end))
170180
)(node);
171181

172-
subjects.push_back({ overlord, subject, SubjectHistory::type_t::UNION, { start, end } });
182+
subjects.emplace_back(overlord, subject, SubjectHistory::type_t::UNION, Period { start, end });
173183
return ret;
174184
},
175185
"substate", ZERO_OR_MORE, [this, &country_definition_manager](ast::NodeCPtr node) -> bool {
@@ -189,7 +199,7 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(
189199
"end_date", ZERO_OR_ONE, expect_date_identifier_or_string(assign_variable_callback(end))
190200
)(node);
191201

192-
subjects.push_back({ overlord, subject, SubjectHistory::type_t::SUBSTATE, { start, end } });
202+
subjects.emplace_back(overlord, subject, SubjectHistory::type_t::SUBSTATE, Period { start, end });
193203
return ret;
194204
},
195205
"reparations", ZERO_OR_MORE, [this, &country_definition_manager](ast::NodeCPtr node) -> bool {
@@ -209,29 +219,45 @@ bool DiplomaticHistoryManager::load_diplomacy_history_file(
209219
"end_date", ZERO_OR_ONE, expect_date_identifier_or_string(assign_variable_callback(end))
210220
)(node);
211221

212-
reparations.push_back({ receiver, sender, { start, end } });
222+
reparations.emplace_back(receiver, sender, Period { start, end });
213223
return ret;
214224
}
215225
)(root);
216226
}
217227

218228
bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& definition_manager, ast::NodeCPtr root) {
219229
std::string_view name {};
220-
std::vector<WarHistory::war_participant_t> attackers {};
221-
std::vector<WarHistory::war_participant_t> defenders {};
222-
std::vector<WarHistory::added_wargoal_t> wargoals {};
230+
231+
// Ensures that if ever multithreaded, only one vector is used per thread
232+
// Else acts like static
233+
thread_local std::vector<WarHistory::war_participant_t> attackers;
234+
// Default max vanilla attackers is 1, 1 is the max I've seen in mods
235+
// Eliminates reallocations
236+
attackers.reserve(1);
237+
238+
thread_local std::vector<WarHistory::war_participant_t> defenders;
239+
// Default max vanilla defenders is 1, 1 is the max I've seen in mods
240+
// Eliminates reallocations
241+
defenders.reserve(1);
242+
243+
thread_local std::vector<WarHistory::added_wargoal_t> wargoals;
244+
// Default max vanilla wargoals is 2, 2 is the max I've seen in mods
245+
// Eliminates reallocations
246+
wargoals.reserve(1);
247+
223248
Date current_date {};
224249

250+
225251
bool ret = expect_dictionary_keys_and_default(
226-
[&definition_manager, &attackers, &defenders, &wargoals, &current_date, &name](
252+
[&definition_manager, &current_date, &name](
227253
std::string_view key, ast::NodeCPtr node
228254
) -> bool {
229255
bool ret = expect_date_str(assign_variable_callback(current_date))(key);
230256

231257
ret &= expect_dictionary_keys(
232258
"add_attacker", ZERO_OR_MORE,
233259
definition_manager.get_country_definition_manager().expect_country_definition_identifier(
234-
[&attackers, &current_date, &name](CountryDefinition const& country) -> bool {
260+
[&current_date, &name](CountryDefinition const& country) -> bool {
235261
for (auto const& attacker : attackers) {
236262
if (attacker.get_country() == &country) {
237263
Logger::error(
@@ -243,13 +269,13 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
243269
}
244270
}
245271

246-
attackers.push_back({ &country, { current_date, {} } });
272+
attackers.emplace_back(&country, Period { current_date, {} });
247273
return true;
248274
}
249275
),
250276
"add_defender", ZERO_OR_MORE,
251277
definition_manager.get_country_definition_manager().expect_country_definition_identifier(
252-
[&defenders, &current_date, &name](CountryDefinition const& country) -> bool {
278+
[&current_date, &name](CountryDefinition const& country) -> bool {
253279
for (auto const& defender : defenders) {
254280
if (defender.get_country() == &country) {
255281
Logger::error(
@@ -261,13 +287,13 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
261287
}
262288
}
263289

264-
defenders.push_back({ &country, { current_date, {} } });
290+
defenders.emplace_back(&country, Period { current_date, {} });
265291
return true;
266292
}
267293
),
268294
"rem_attacker", ZERO_OR_MORE,
269295
definition_manager.get_country_definition_manager().expect_country_definition_identifier(
270-
[&attackers, &current_date, &name](CountryDefinition const& country) -> bool {
296+
[&current_date, &name](CountryDefinition const& country) -> bool {
271297
WarHistory::war_participant_t* participant_to_remove = nullptr;
272298

273299
for (auto& attacker : attackers) {
@@ -291,7 +317,7 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
291317
),
292318
"rem_defender", ZERO_OR_MORE,
293319
definition_manager.get_country_definition_manager().expect_country_definition_identifier(
294-
[&defenders, &current_date, &name](CountryDefinition const& country) -> bool {
320+
[&current_date, &name](CountryDefinition const& country) -> bool {
295321
WarHistory::war_participant_t* participant_to_remove = nullptr;
296322

297323
for (auto& defender : defenders) {
@@ -313,7 +339,7 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
313339
return participant_to_remove->period.try_set_end(current_date);
314340
}
315341
),
316-
"war_goal", ZERO_OR_MORE, [&definition_manager, &wargoals, &current_date](ast::NodeCPtr value) -> bool {
342+
"war_goal", ZERO_OR_MORE, [&definition_manager, &current_date](ast::NodeCPtr value) -> bool {
317343
CountryDefinition const* actor = nullptr;
318344
CountryDefinition const* receiver = nullptr;
319345
WargoalType const* type = nullptr;
@@ -341,7 +367,7 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
341367
)
342368
)(value);
343369

344-
wargoals.push_back({ current_date, actor, receiver, type, third_party, target });
370+
wargoals.emplace_back(current_date, actor, receiver, type, third_party, target);
345371
return ret;
346372
}
347373
)(node);
@@ -351,7 +377,7 @@ bool DiplomaticHistoryManager::load_war_history_file(DefinitionManager const& de
351377
"name", ZERO_OR_ONE, expect_string(assign_variable_callback(name))
352378
)(root);
353379

354-
wars.push_back({ name, std::move(attackers), std::move(defenders), std::move(wargoals) });
380+
wars.emplace_back(name, std::move(attackers), std::move(defenders), std::move(wargoals));
355381

356382
return ret;
357383
}

src/openvic-simulation/history/DiplomaticHistory.hpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ namespace OpenVic {
2020
struct added_wargoal_t {
2121
friend struct DiplomaticHistoryManager;
2222

23+
added_wargoal_t(
24+
Date new_added, CountryDefinition const* new_actor, CountryDefinition const* new_receiver,
25+
WargoalType const* new_wargoal, std::optional<CountryDefinition const*> new_third_party,
26+
std::optional<ProvinceDefinition const*> new_target
27+
);
28+
2329
private:
2430
Date PROPERTY_CUSTOM_PREFIX(added, get_date);
2531
CountryDefinition const* PROPERTY(actor);
@@ -29,23 +35,24 @@ namespace OpenVic {
2935
// TODO - could these just be nullptr when unset rather than using optionals?
3036
std::optional<CountryDefinition const*> PROPERTY(third_party);
3137
std::optional<ProvinceDefinition const*> PROPERTY(target);
32-
33-
added_wargoal_t(
34-
Date new_added, CountryDefinition const* new_actor, CountryDefinition const* new_receiver,
35-
WargoalType const* new_wargoal, std::optional<CountryDefinition const*> new_third_party,
36-
std::optional<ProvinceDefinition const*> new_target
37-
);
3838
};
39+
static_assert(std::is_trivially_move_constructible_v<added_wargoal_t>);
3940

4041
struct war_participant_t {
4142
friend struct DiplomaticHistoryManager;
4243

44+
war_participant_t(CountryDefinition const* new_country, Period period);
45+
4346
private:
4447
CountryDefinition const* PROPERTY(country);
4548
Period PROPERTY(period);
46-
47-
war_participant_t(CountryDefinition const* new_country, Period period);
4849
};
50+
static_assert(std::is_trivially_move_constructible_v<war_participant_t>);
51+
52+
WarHistory(
53+
std::string_view new_war_name, std::vector<war_participant_t>&& new_attackers,
54+
std::vector<war_participant_t>&& new_defenders, std::vector<added_wargoal_t>&& new_wargoals
55+
);
4956

5057
private:
5158
/* Edge cases where this is empty/undef for some reason,
@@ -54,54 +61,52 @@ namespace OpenVic {
5461
std::vector<war_participant_t> PROPERTY(attackers);
5562
std::vector<war_participant_t> PROPERTY(defenders);
5663
std::vector<added_wargoal_t> PROPERTY(wargoals);
57-
58-
WarHistory(
59-
std::string_view new_war_name, std::vector<war_participant_t>&& new_attackers,
60-
std::vector<war_participant_t>&& new_defenders, std::vector<added_wargoal_t>&& new_wargoals
61-
);
6264
};
6365

6466
struct AllianceHistory {
6567
friend struct DiplomaticHistoryManager;
6668

69+
AllianceHistory(CountryDefinition const* new_first, CountryDefinition const* new_second, Period period);
70+
6771
private:
6872
CountryDefinition const* PROPERTY(first);
6973
CountryDefinition const* PROPERTY(second);
7074
const Period PROPERTY(period);
71-
72-
AllianceHistory(CountryDefinition const* new_first, CountryDefinition const* new_second, Period period);
7375
};
76+
static_assert(std::is_trivially_move_constructible_v<AllianceHistory>);
7477

7578
struct ReparationsHistory {
7679
friend struct DiplomaticHistoryManager;
7780

81+
ReparationsHistory(CountryDefinition const* new_receiver, CountryDefinition const* new_sender, Period period);
82+
7883
private:
7984
CountryDefinition const* PROPERTY(receiver);
8085
CountryDefinition const* PROPERTY(sender);
8186
const Period PROPERTY(period);
82-
83-
ReparationsHistory(CountryDefinition const* new_receiver, CountryDefinition const* new_sender, Period period);
8487
};
88+
static_assert(std::is_trivially_move_constructible_v<ReparationsHistory>);
8589

8690
struct SubjectHistory {
8791
friend struct DiplomaticHistoryManager;
8892

89-
enum class type_t {
93+
enum class type_t : uint8_t {
9094
VASSAL,
9195
UNION,
9296
SUBSTATE
9397
};
9498

99+
SubjectHistory(
100+
CountryDefinition const* new_overlord, CountryDefinition const* new_subject, type_t new_type, Period period
101+
);
102+
95103
private:
96104
CountryDefinition const* PROPERTY(overlord);
97105
CountryDefinition const* PROPERTY(subject);
98106
const type_t PROPERTY_CUSTOM_PREFIX(type, get_subject);
99107
const Period PROPERTY(period);
100-
101-
SubjectHistory(
102-
CountryDefinition const* new_overlord, CountryDefinition const* new_subject, type_t new_type, Period period
103-
);
104108
};
109+
static_assert(std::is_trivially_move_constructible_v<SubjectHistory>);
105110

106111
struct CountryDefinitionManager;
107112
struct DefinitionManager;

0 commit comments

Comments
 (0)