diff options
author | Jacques Lucke <jacques@blender.org> | 2022-05-31 21:41:01 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-05-31 21:41:01 +0300 |
commit | 5c80bcf8c2fbd1e3c71ef5169f59e0b95c4db153 (patch) | |
tree | b356acfe3114e062384822fcb7ac93028a267250 /source/blender/blenlib/BLI_virtual_array.hh | |
parent | 484ea573af376a483ae7ecd0c1cba95ac5b122c7 (diff) |
Functions: speedup preparing multi-function parameters
My benchmark which spend most time preparing function parameters
takes `250 ms` now, from `510 ms` before. This is mainly achieved by
doing less unnecessary work and by giving the compiler more inlined
code to optimize.
* Reserve correct vector sizes and use unchecked `append` function.
* Construct `GVArray` parameters directly in the vector, instead of
moving/copying them in the vector afterwards.
* Inline some constructors, because that allows the compiler understand
what is happening, resulting in less code.
This probably has negilible impact on the user experience currently,
because there are other bottlenecks.
Differential Revision: https://developer.blender.org/D15009
Diffstat (limited to 'source/blender/blenlib/BLI_virtual_array.hh')
-rw-r--r-- | source/blender/blenlib/BLI_virtual_array.hh | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 6efd1d6d769..ab4ca185ddb 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -872,6 +872,22 @@ template<typename T> class VArrayCommon { template<typename T> class VMutableArray; /** + * Various tags to disambiguate constructors of virtual arrays. + * Generally it is easier to use `VArray::For*` functions to construct virtual arrays, but + * sometimes being able to use the constructor can result in better performance For example, when + * constructing the virtual array directly in a vector. Without the constructor one would have to + * construct the virtual array first and then move it into the vector. + */ +namespace varray_tag { +struct span { +}; +struct single_ref { +}; +struct single { +}; +} // namespace varray_tag + +/** * A #VArray wraps a virtual array implementation and provides easy access to its elements. It can * be copied and moved. While it is relatively small, it should still be passed by reference if * possible (other than e.g. #Span). @@ -892,6 +908,19 @@ template<typename T> class VArray : public VArrayCommon<T> { { } + VArray(varray_tag::span /* tag */, Span<T> span) + { + /* Cast const away, because the virtual array implementation for const and non const spans is + * shared. */ + MutableSpan<T> mutable_span{const_cast<T *>(span.data()), span.size()}; + this->template emplace<VArrayImpl_For_Span_final<T>>(mutable_span); + } + + VArray(varray_tag::single /* tag */, T value, const int64_t size) + { + this->template emplace<VArrayImpl_For_Single<T>>(std::move(value), size); + } + /** * Construct a new virtual array for a custom #VArrayImpl. */ @@ -908,7 +937,7 @@ template<typename T> class VArray : public VArrayCommon<T> { */ static VArray ForSingle(T value, const int64_t size) { - return VArray::For<VArrayImpl_For_Single<T>>(std::move(value), size); + return VArray(varray_tag::single{}, std::move(value), size); } /** @@ -917,10 +946,7 @@ template<typename T> class VArray : public VArrayCommon<T> { */ static VArray ForSpan(Span<T> values) { - /* Cast const away, because the virtual array implementation for const and non const spans is - * shared. */ - MutableSpan<T> span{const_cast<T *>(values.data()), values.size()}; - return VArray::For<VArrayImpl_For_Span_final<T>>(span); + return VArray(varray_tag::span{}, values); } /** |