Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lightweight crafting inventory to improve NPC construction time #46286

Merged

Conversation

Aivean
Copy link
Contributor

@Aivean Aivean commented Dec 24, 2020

Summary

SUMMARY: Performance "Add lightweight crafting inventory to improve NPC construction time"

Purpose of change

Fixes #41220 (performance)

Currently, when performing crafting/construction, NPC for each stack of components has to invoke requirements_map which, in turn, invokes are_requirements_nearby.

are_requirements_nearby constructs temporary inventory, which includes all items in the 60 tile radius. Current implementation of the inventory is highly inefficient, namely:

  • it always copies items
  • by default it stacks items and manages assigned letters

Temporary inventory is constructed, checked once against a single requirement and immediately discarded afterwards.

Describe the solution

The gist of the solution is to use lightweight wrapper around cata::colony<item *> instead of inventory (which is internally list<list<item>>).

However, to achieve this seemingly simple task, I had to:

  • Remove template parameter from visitable<T> interface (replace it with virtual inheritance).
    Reason: visitable<A> and visitable<B> are two different classes, while all descendants of just visitable share the common interface, which can (and should) be used as an argument in different crafting check methods
  • Split visitable into read_only_visitable (doesn't allow item removal) and visitable (inherits read_only_visitable, adds remove_item and remove_items_with)
  • Change most of the methods that previously accepted inventory parameter to accept read_only_visitable instead
  • Create a lightweight wrapper around cata::colony<item *> which inherits from read_only_visitable
  • Use this new wrapper (called temp_crafting_inventory ) instead of inventory in are_requirements_nearby

Note to reviewers: all commits in this PR are logical stages of the implementation (that correspond to the items above) and pass unit tests in isolation, so I suggest to review this PR one commit at a time to reduce the scope.

Describe alternatives you've considered

I probably could've left the template parameter in visitable, but then all crafting checks would have to be templated and moved to the header, which doesn't seem ideal. I think, having visitable as a simple interface is a better design choice.

Testing

Playtesting.
Also added unit tests for the new temp_crafting_inventory and changed the current crafting tests for inventory to also check the temp_crafting_inventory.

Additional context

There are multiple places in the codebase where inventory is created, queried couple of times and immediately discarded. Also, there is Character::crafting_inventory. In the future, I plan to replace all of that with the new temp_crafting_inventory.

Demo:

Before:
woodchip_before

After:
woodchip_after

Profiling results coming soon...

@Aivean Aivean added [C++] Changes (can be) made in C++. Previously named `Code` Code: Performance Performance boosting code (CPU, memory, etc.) Crafting / Construction / Recipes Includes: Uncrafting / Disassembling NPC / Factions NPCs, AI, Speech, Factions, Ownership labels Dec 24, 2020
@Aivean Aivean marked this pull request as draft December 24, 2020 06:44
@Aivean Aivean force-pushed the lightweight-crafting-inventory branch from e4d9430 to f0557c9 Compare December 24, 2020 23:29
@Aivean
Copy link
Contributor Author

Aivean commented Dec 24, 2020

Profiling

Before:
image

After:
image

@Aivean Aivean force-pushed the lightweight-crafting-inventory branch from f0557c9 to c123cc4 Compare December 25, 2020 00:09
@Aivean Aivean marked this pull request as ready for review December 25, 2020 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C++] Changes (can be) made in C++. Previously named `Code` Code: Performance Performance boosting code (CPU, memory, etc.) Crafting / Construction / Recipes Includes: Uncrafting / Disassembling NPC / Factions NPCs, AI, Speech, Factions, Ownership
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Game freeze when telling NPC to construct woodchip floor in basecamp
2 participants