diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-21 14:37:04 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-21 14:48:07 +0300 |
commit | 6ee2abde82ef121cd6e927995053ac33afdbb438 (patch) | |
tree | f2ed1bb0962c0ea60c30ba7d9dea2a6e184ec247 /source/blender/functions/intern | |
parent | d455eadcd82f2151e858025cae6788b65016811e (diff) |
Functions: use static names for multi-functions
Previously, the function names were stored in `std::string` and were often
created dynamically (especially when the function just output a constant).
This resulted in a lot of overhead.
Now the function name is just a `const char *` that should be statically
allocated. This is good enough for the majority of cases. If a multi-function
needs a more dynamic name, it can override the `MultiFunction::debug_name`
method.
In my test file with >400,000 simple math nodes, the execution time improves from
3s to 1s.
Diffstat (limited to 'source/blender/functions/intern')
5 files changed, 19 insertions, 36 deletions
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 68a8446e6ae..91b1bdfd8f0 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -237,8 +237,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, if (!already_output_variables.add(variable)) { /* One variable can be output at most once. To output the same value twice, we have to make * a copy first. */ - const MultiFunction ©_fn = scope.construct<CustomMF_GenericCopy>("copy", - variable->data_type()); + const MultiFunction ©_fn = scope.construct<CustomMF_GenericCopy>(variable->data_type()); variable = builder.add_call<1>(copy_fn, {variable})[0]; } builder.add_output_parameter(*variable); @@ -358,7 +357,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope, MFProcedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, varying_fields_to_evaluate); - MFProcedureExecutor procedure_executor{"Procedure", procedure}; + MFProcedureExecutor procedure_executor{procedure}; /* Add multi threading capabilities to the field evaluation. */ const int grain_size = 10000; fn::ParallelMultiFunction parallel_procedure_executor{procedure_executor, grain_size}; @@ -415,7 +414,7 @@ Vector<GVArray> evaluate_fields(ResourceScope &scope, MFProcedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, constant_fields_to_evaluate); - MFProcedureExecutor procedure_executor{"Procedure", procedure}; + MFProcedureExecutor procedure_executor{procedure}; MFParamsBuilder mf_params{procedure_executor, 1}; MFContextBuilder mf_context; diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index 43eacdcd2a1..ee2c69068db 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -18,4 +18,9 @@ namespace blender::fn { +std::string MultiFunction::debug_name() const +{ + return signature_ref_->function_name; +} + } // namespace blender::fn diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index f891f162820..24f9bbe0179 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -32,10 +32,8 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, } value_ = value; - MFSignatureBuilder signature{"Constant " + type.name()}; - std::stringstream ss; - type.print_or_default(value, ss, type.name()); - signature.single_output(ss.str(), type); + MFSignatureBuilder signature{"Constant"}; + signature.single_output("Value", type); signature_ = signature.build(); this->set_signature(&signature_); } @@ -73,28 +71,11 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const return type_.is_equal(value_, _other->value_); } -static std::string gspan_to_string(GSpan array) -{ - const CPPType &type = array.type(); - std::stringstream ss; - ss << "["; - const int64_t max_amount = 5; - for (int64_t i : IndexRange(std::min(max_amount, array.size()))) { - type.print_or_default(array[i], ss, type.name()); - ss << ", "; - } - if (max_amount < array.size()) { - ss << "..."; - } - ss << "]"; - return ss.str(); -} - CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array) { const CPPType &type = array.type(); - MFSignatureBuilder signature{"Constant " + type.name() + " Vector"}; - signature.vector_output(gspan_to_string(array), type); + MFSignatureBuilder signature{"Constant Vector"}; + signature.vector_output("Value", type); signature_ = signature.build(); this->set_signature(&signature_); } @@ -109,12 +90,11 @@ void CustomMF_GenericConstantArray::call(IndexMask mask, } } -CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name, - Span<MFDataType> input_types, +CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span<MFDataType> input_types, Span<MFDataType> output_types) : output_amount_(output_types.size()) { - MFSignatureBuilder signature{name}; + MFSignatureBuilder signature{"Default Output"}; for (MFDataType data_type : input_types) { signature.input("Input", data_type); } @@ -140,9 +120,9 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNU } } -CustomMF_GenericCopy::CustomMF_GenericCopy(StringRef name, MFDataType data_type) +CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type) { - MFSignatureBuilder signature{name}; + MFSignatureBuilder signature{"Copy"}; signature.input("Input", data_type); signature.output("Output", data_type); signature_ = signature.build(); diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc index 986c5dff0c4..804beb7d66f 100644 --- a/source/blender/functions/intern/multi_function_procedure.cc +++ b/source/blender/functions/intern/multi_function_procedure.cc @@ -782,7 +782,7 @@ class MFProcedureDotExport { void instruction_to_string(const MFCallInstruction &instruction, std::stringstream &ss) { const MultiFunction &fn = instruction.fn(); - this->instruction_name_format(fn.name() + ": ", ss); + this->instruction_name_format(fn.debug_name() + ": ", ss); for (const int param_index : fn.param_indices()) { const MFParamType param_type = fn.param_type(param_index); const MFVariable *variable = instruction.params()[param_index]; diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index 85d0cf4909f..1136b03ed58 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -20,10 +20,9 @@ namespace blender::fn { -MFProcedureExecutor::MFProcedureExecutor(std::string name, const MFProcedure &procedure) - : procedure_(procedure) +MFProcedureExecutor::MFProcedureExecutor(const MFProcedure &procedure) : procedure_(procedure) { - MFSignatureBuilder signature(std::move(name)); + MFSignatureBuilder signature("Procedure Executor"); for (const ConstMFParameter ¶m : procedure.params()) { signature.add(param.variable->name(), MFParamType(param.type, param.variable->data_type())); |