From 46c23e1758dc300a3929ec5e1d13eb7913d3febc Mon Sep 17 00:00:00 2001 From: HP van Braam Date: Wed, 25 Dec 2024 01:03:15 +0100 Subject: [PATCH] Don't set Variant::Type in destructor When profiling Dome Keeper, I found that in physics_process a HashMap gets cleared a lot, which ends up calling the Variant destructor. Calling Variant::clear() dominates this operation. By not uselessly setting the Type to NIL on destruction we save about 50% of time. This is likely because if there is a simple type in the Variant that doesn't need destructing, but now we write when we should just drop the Variant altogether. Since the value of Variant::type should be unobservable after destruction this doesn't change any outward behavior. --- core/variant/variant.h | 96 +++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/core/variant/variant.h b/core/variant/variant.h index 736e03264b2..ede1535e0c1 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -275,53 +275,53 @@ private: void _clear_internal(); + static constexpr bool needs_deinit[Variant::VARIANT_MAX] = { + false, //NIL, + false, //BOOL, + false, //INT, + false, //FLOAT, + true, //STRING, + false, //VECTOR2, + false, //VECTOR2I, + false, //RECT2, + false, //RECT2I, + false, //VECTOR3, + false, //VECTOR3I, + true, //TRANSFORM2D, + false, //VECTOR4, + false, //VECTOR4I, + false, //PLANE, + false, //QUATERNION, + true, //AABB, + true, //BASIS, + true, //TRANSFORM, + true, //PROJECTION, + + // misc types + false, //COLOR, + true, //STRING_NAME, + true, //NODE_PATH, + false, //RID, + true, //OBJECT, + true, //CALLABLE, + true, //SIGNAL, + true, //DICTIONARY, + true, //ARRAY, + + // typed arrays + true, //PACKED_BYTE_ARRAY, + true, //PACKED_INT32_ARRAY, + true, //PACKED_INT64_ARRAY, + true, //PACKED_FLOAT32_ARRAY, + true, //PACKED_FLOAT64_ARRAY, + true, //PACKED_STRING_ARRAY, + true, //PACKED_VECTOR2_ARRAY, + true, //PACKED_VECTOR3_ARRAY, + true, //PACKED_COLOR_ARRAY, + true, //PACKED_VECTOR4_ARRAY, + }; + _FORCE_INLINE_ void clear() { - static const bool needs_deinit[Variant::VARIANT_MAX] = { - false, //NIL, - false, //BOOL, - false, //INT, - false, //FLOAT, - true, //STRING, - false, //VECTOR2, - false, //VECTOR2I, - false, //RECT2, - false, //RECT2I, - false, //VECTOR3, - false, //VECTOR3I, - true, //TRANSFORM2D, - false, //VECTOR4, - false, //VECTOR4I, - false, //PLANE, - false, //QUATERNION, - true, //AABB, - true, //BASIS, - true, //TRANSFORM, - true, //PROJECTION, - - // misc types - false, //COLOR, - true, //STRING_NAME, - true, //NODE_PATH, - false, //RID, - true, //OBJECT, - true, //CALLABLE, - true, //SIGNAL, - true, //DICTIONARY, - true, //ARRAY, - - // typed arrays - true, //PACKED_BYTE_ARRAY, - true, //PACKED_INT32_ARRAY, - true, //PACKED_INT64_ARRAY, - true, //PACKED_FLOAT32_ARRAY, - true, //PACKED_FLOAT64_ARRAY, - true, //PACKED_STRING_ARRAY, - true, //PACKED_VECTOR2_ARRAY, - true, //PACKED_VECTOR3_ARRAY, - true, //PACKED_COLOR_ARRAY, - true, //PACKED_VECTOR4_ARRAY, - }; - if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit. _clear_internal(); } @@ -832,7 +832,9 @@ public: } _FORCE_INLINE_ Variant() {} _FORCE_INLINE_ ~Variant() { - clear(); + if (unlikely(needs_deinit[type])) { // Make it fast for types that don't need deinit. + _clear_internal(); + } } };