diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-24 19:46:00 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-24 19:46:00 +0300 |
commit | cbe9a87d282f8060670b2162a87995a255dda556 (patch) | |
tree | 326fd89453379da15a264f44c0d10edecdb2e9bf /source/blender/blenlib | |
parent | e206a0ae960c2c62df6ece863bf855dda581d4f1 (diff) |
Geometry Nodes: use simpler types when devirtualizing virtual array
The compiler is more likely to optimize away the function call
overhead when the used type is simpler and not virtual.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_virtual_array.hh | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index d9f83d3e1cb..b8b05e88572 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -1107,6 +1107,30 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> { } }; +template<typename T> class SingleAsSpan { + private: + T value_; + int64_t size_; + + public: + SingleAsSpan(T value, int64_t size) : value_(std::move(value)), size_(size) + { + BLI_assert(size_ >= 0); + } + + SingleAsSpan(const VArray<T> &varray) : SingleAsSpan(varray.get_internal_single(), varray.size()) + { + } + + const T &operator[](const int64_t index) const + { + BLI_assert(index >= 0); + BLI_assert(index < size_); + UNUSED_VARS_NDEBUG(index); + return value_; + } +}; + /** * Generate multiple versions of the given function optimized for different virtual arrays. * One has to be careful with nesting multiple devirtualizations, because that results in an @@ -1121,14 +1145,11 @@ inline void devirtualize_varray(const VArray<T> &varray, const Func &func, bool /* Support disabling the devirtualization to simplify benchmarking. */ if (enable) { if (varray.is_single()) { - /* `VArrayImpl_For_Single` can be used for devirtualization, because it is declared `final`. - */ - func(VArray<T>::ForSingle(varray.get_internal_single(), varray.size())); + func(SingleAsSpan<T>(varray)); return; } if (varray.is_span()) { - /* `VArrayImpl_For_Span` can be used for devirtualization, because it is declared `final`. */ - func(VArray<T>::ForSpan(varray.get_internal_span())); + func(varray.get_internal_span()); return; } } @@ -1153,23 +1174,19 @@ inline void devirtualize_varray2(const VArray<T1> &varray1, const bool is_single1 = varray1.is_single(); const bool is_single2 = varray2.is_single(); if (is_span1 && is_span2) { - func(VArray<T1>::ForSpan(varray1.get_internal_span()), - VArray<T2>::ForSpan(varray2.get_internal_span())); + func(varray1.get_internal_span(), varray2.get_internal_span()); return; } if (is_span1 && is_single2) { - func(VArray<T1>::ForSpan(varray1.get_internal_span()), - VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size())); + func(varray1.get_internal_span(), SingleAsSpan(varray2)); return; } if (is_single1 && is_span2) { - func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()), - VArray<T2>::ForSpan(varray2.get_internal_span())); + func(SingleAsSpan(varray1), varray2.get_internal_span()); return; } if (is_single1 && is_single2) { - func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()), - VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size())); + func(SingleAsSpan(varray1), SingleAsSpan(varray2)); return; } } |