From b513c89e8450289746a7b3397bf3d610a0989d79 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 25 Jun 2022 18:52:55 +0200 Subject: Functions: avoid using Map for small values This leads to a 5-10% performance improvement in my benchmark that runs a procedure many times on a single element. --- .../intern/multi_function_procedure_executor.cc | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source/blender/functions/intern') diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index a45240dad55..d92ce80bceb 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -147,11 +147,11 @@ class ValueAllocator : NonCopyable, NonMovable { Map> span_buffers_free_list_; /** Cache buffers for single values of different types. */ + static constexpr inline int small_value_max_size = 16; + static constexpr inline int small_value_max_alignment = 8; + Stack small_single_value_free_list_; Map> single_value_free_lists_; - /** The cached memory buffers can hold #VariableState values. */ - Stack variable_state_free_list_; - public: ValueAllocator(LinearAllocator<> &linear_allocator) : linear_allocator_(linear_allocator) { @@ -210,10 +210,15 @@ class ValueAllocator : NonCopyable, NonMovable { VariableValue_OneSingle *obtain_OneSingle(const CPPType &type) { - Stack &stack = single_value_free_lists_.lookup_or_add_default(&type); + const bool is_small = type.can_exist_in_buffer(small_value_max_size, + small_value_max_alignment); + Stack &stack = is_small ? small_single_value_free_list_ : + single_value_free_lists_.lookup_or_add_default(&type); void *buffer; if (stack.is_empty()) { - buffer = linear_allocator_.allocate(type.size(), type.alignment()); + buffer = linear_allocator_.allocate( + std::max(small_value_max_size, type.size()), + std::max(small_value_max_alignment, type.alignment())); } else { buffer = stack.pop(); @@ -259,7 +264,14 @@ class ValueAllocator : NonCopyable, NonMovable { if (value_typed->is_initialized) { type.destruct(value_typed->data); } - single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data); + const bool is_small = type.can_exist_in_buffer(small_value_max_size, + small_value_max_alignment); + if (is_small) { + small_single_value_free_list_.push(value_typed->data); + } + else { + single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data); + } break; } case ValueType::OneVector: { -- cgit v1.2.3