diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 4c8a67f81b3..8075694edca 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1078,6 +1078,33 @@ class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction { { return 2 * i + 1; } + + /** + * Cache for functions small amounts to avoid to avoid building them many times. + */ + static const LazyFunctionForAnonymousAttributeSetJoin &get_cached( + const int amount, Vector> &r_functions) + { + constexpr int cache_amount = 16; + static std::array cached_functions = + get_cache(std::make_index_sequence{}); + if (amount <= cached_functions.size()) { + return cached_functions[amount]; + } + + auto fn = std::make_unique(amount); + const auto &fn_ref = *fn; + r_functions.append(std::move(fn)); + return fn_ref; + } + + private: + template + static std::array get_cache( + std::index_sequence /*indices*/) + { + return {LazyFunctionForAnonymousAttributeSetJoin(I)...}; + } }; enum class AttributeReferenceKeyType { @@ -2529,18 +2556,17 @@ struct GeometryNodesLazyFunctionGraphBuilder { key.extend(used_sockets); std::sort(key.begin(), key.end()); return cache.lookup_or_add_cb(key, [&]() { - auto lazy_function = std::make_unique( - attribute_set_sockets.size()); - lf::Node &lf_node = lf_graph_->add_function(*lazy_function); + const auto &lazy_function = LazyFunctionForAnonymousAttributeSetJoin::get_cached( + attribute_set_sockets.size(), lf_graph_info_->functions); + lf::Node &lf_node = lf_graph_->add_function(lazy_function); for (const int i : attribute_set_sockets.index_range()) { - lf::InputSocket &lf_use_input = lf_node.input(lazy_function->get_use_input(i)); + lf::InputSocket &lf_use_input = lf_node.input(lazy_function.get_use_input(i)); socket_usage_inputs_.add(&lf_use_input); lf::InputSocket &lf_attributes_input = lf_node.input( - lazy_function->get_attribute_set_input(i)); + lazy_function.get_attribute_set_input(i)); lf_graph_->add_link(*used_sockets[i], lf_use_input); lf_graph_->add_link(*attribute_set_sockets[i], lf_attributes_input); } - lf_graph_info_->functions.append(std::move(lazy_function)); return &lf_node.output(0); }); }