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

Improve performance of materials::get_rotting #44544

Merged
merged 1 commit into from
Oct 2, 2020

Conversation

Aivean
Copy link
Contributor

@Aivean Aivean commented Oct 1, 2020

Summary

SUMMARY: Performance "Improve performance of materials::get_rotting"

Purpose of change

While waiting for the long time near a building with many rotting corpses, I noticed that materials::get_rotting shows up in profiler.

Describe the solution

Before materials::get_rotting was filtering the whole list of materials to find those susceptible to rot.

I reused the new versioning mechanism in generic_factory(see #44261) to create a static cache that is invalidated with corresponding generic_factory.

Then I used such cache to cache the set of materials inside the materials::get_rotting.

Describe alternatives you've considered

At first I thought of implementing "versioned cache" in the following way:

template<typename C>
    class cache {
        friend generic_factory<T>;

        int64_t& factory_verion;
        int64_t cache_verion;
        std::function<C()> init;
        C value;

        cache(int64_t &factoryVerion, const std::function<C()> &init) : factory_verion(
                factoryVerion), cache_verion(factoryVerion), init(init), value(init()) {}

    public:
        cache(const cache&) = default;
        C& get_value() {
            if (cache_verion != factory_verion) {
                value = init();
                cache_verion = factory_verion;
            }
            return value;
        }
    };


template<typename C>
cache<C> generic_factory::create_cache(std::function<C()> init) {
    return cache<C> (version, init);
}

However, I figured the reference to the generic_factory version int64_t& factory_verion; is unsafe if generic factory is not static, so I went with simpler and safer albeit less "pretty" solution.

Testing

With debugger I ensured that cache is initialized and reused correctly, and also invalidated and reinitialized when game reloads.
Also added unit tests.

Additional context

Profiling results.

Before:
image

After:
image

Note, that although the set of rotting materials is passed around by value, compiler seems to optimize that away, as the set is constant.

…s that are invalidated together with corresponding generic_factory

use the new versioned cache to optimize performance of materials::get_rotting
@ZhilkinSerg ZhilkinSerg merged commit 602e91b into CleverRaven:master Oct 2, 2020
@Aivean Aivean deleted the optimize-rot-check branch October 27, 2020 21:26
@anothersimulacrum anothersimulacrum added [C++] Changes (can be) made in C++. Previously named `Code` Code: Performance Performance boosting code (CPU, memory, etc.) labels Nov 8, 2020
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.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants