Don't call Variant::reference() unnecessarily

operator= does not need to call reference() if the new value is of the
same type as the old. This saves us zeroing the Variant, This speeds
up reuse of a Variant in a loop by roughly 50%.
This commit is contained in:
Hein-Pieter van Braam 2017-09-19 01:46:48 +02:00
parent 60790c8c5a
commit d05965963d

View file

@ -903,9 +903,6 @@ bool Variant::is_one() const {
void Variant::reference(const Variant &p_variant) { void Variant::reference(const Variant &p_variant) {
if (this == &p_variant)
return;
clear(); clear();
type = p_variant.type; type = p_variant.type;
@ -924,17 +921,14 @@ void Variant::reference(const Variant &p_variant) {
case INT: { case INT: {
_data._int = p_variant._data._int; _data._int = p_variant._data._int;
} break; } break;
case REAL: { case REAL: {
_data._real = p_variant._data._real; _data._real = p_variant._data._real;
} break; } break;
case STRING: { case STRING: {
memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem))); memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem)));
} break; } break;
// math types // math types
@ -942,33 +936,24 @@ void Variant::reference(const Variant &p_variant) {
case VECTOR2: { case VECTOR2: {
memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem))); memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem)));
} break; } break;
case RECT2: { case RECT2: {
memnew_placement(_data._mem, Rect2(*reinterpret_cast<const Rect2 *>(p_variant._data._mem))); memnew_placement(_data._mem, Rect2(*reinterpret_cast<const Rect2 *>(p_variant._data._mem)));
} break; } break;
case TRANSFORM2D: { case TRANSFORM2D: {
_data._transform2d = memnew(Transform2D(*p_variant._data._transform2d)); _data._transform2d = memnew(Transform2D(*p_variant._data._transform2d));
} break; } break;
case VECTOR3: { case VECTOR3: {
memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem))); memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem)));
} break; } break;
case PLANE: { case PLANE: {
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
} break; } break;
/*
case QUAT: {
} break;*/
case RECT3: { case RECT3: {
_data._rect3 = memnew(Rect3(*p_variant._data._rect3)); _data._rect3 = memnew(Rect3(*p_variant._data._rect3));
@ -986,7 +971,6 @@ void Variant::reference(const Variant &p_variant) {
case TRANSFORM: { case TRANSFORM: {
_data._transform = memnew(Transform(*p_variant._data._transform)); _data._transform = memnew(Transform(*p_variant._data._transform));
} break; } break;
// misc types // misc types
@ -1058,6 +1042,7 @@ void Variant::reference(const Variant &p_variant) {
default: {} default: {}
} }
} }
void Variant::zero() { void Variant::zero() {
switch (type) { switch (type) {
case NIL: break; case NIL: break;
@ -1073,6 +1058,7 @@ void Variant::zero() {
default: this->clear(); break; default: this->clear(); break;
} }
} }
void Variant::clear() { void Variant::clear() {
switch (type) { switch (type) {
@ -1092,12 +1078,10 @@ void Variant::clear() {
case TRANSFORM2D: { case TRANSFORM2D: {
memdelete(_data._transform2d); memdelete(_data._transform2d);
} break; } break;
case RECT3: { case RECT3: {
memdelete(_data._rect3); memdelete(_data._rect3);
} break; } break;
case BASIS: { case BASIS: {
@ -1106,14 +1090,12 @@ void Variant::clear() {
case TRANSFORM: { case TRANSFORM: {
memdelete(_data._transform); memdelete(_data._transform);
} break; } break;
// misc types // misc types
case NODE_PATH: { case NODE_PATH: {
reinterpret_cast<NodePath *>(_data._mem)->~NodePath(); reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
} break; } break;
case OBJECT: { case OBJECT: {
@ -1127,48 +1109,39 @@ void Variant::clear() {
case DICTIONARY: { case DICTIONARY: {
reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary(); reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary();
} break; } break;
case ARRAY: { case ARRAY: {
reinterpret_cast<Array *>(_data._mem)->~Array(); reinterpret_cast<Array *>(_data._mem)->~Array();
} break; } break;
// arrays // arrays
case POOL_BYTE_ARRAY: { case POOL_BYTE_ARRAY: {
reinterpret_cast<PoolVector<uint8_t> *>(_data._mem)->~PoolVector<uint8_t>(); reinterpret_cast<PoolVector<uint8_t> *>(_data._mem)->~PoolVector<uint8_t>();
} break; } break;
case POOL_INT_ARRAY: { case POOL_INT_ARRAY: {
reinterpret_cast<PoolVector<int> *>(_data._mem)->~PoolVector<int>(); reinterpret_cast<PoolVector<int> *>(_data._mem)->~PoolVector<int>();
} break; } break;
case POOL_REAL_ARRAY: { case POOL_REAL_ARRAY: {
reinterpret_cast<PoolVector<real_t> *>(_data._mem)->~PoolVector<real_t>(); reinterpret_cast<PoolVector<real_t> *>(_data._mem)->~PoolVector<real_t>();
} break; } break;
case POOL_STRING_ARRAY: { case POOL_STRING_ARRAY: {
reinterpret_cast<PoolVector<String> *>(_data._mem)->~PoolVector<String>(); reinterpret_cast<PoolVector<String> *>(_data._mem)->~PoolVector<String>();
} break; } break;
case POOL_VECTOR2_ARRAY: { case POOL_VECTOR2_ARRAY: {
reinterpret_cast<PoolVector<Vector2> *>(_data._mem)->~PoolVector<Vector2>(); reinterpret_cast<PoolVector<Vector2> *>(_data._mem)->~PoolVector<Vector2>();
} break; } break;
case POOL_VECTOR3_ARRAY: { case POOL_VECTOR3_ARRAY: {
reinterpret_cast<PoolVector<Vector3> *>(_data._mem)->~PoolVector<Vector3>(); reinterpret_cast<PoolVector<Vector3> *>(_data._mem)->~PoolVector<Vector3>();
} break; } break;
case POOL_COLOR_ARRAY: { case POOL_COLOR_ARRAY: {
reinterpret_cast<PoolVector<Color> *>(_data._mem)->~PoolVector<Color>(); reinterpret_cast<PoolVector<Color> *>(_data._mem)->~PoolVector<Color>();
} break; } break;
default: {} /* not needed */ default: {} /* not needed */
} }
@ -2496,7 +2469,135 @@ Variant::Variant(const Vector<Color> &p_array) {
void Variant::operator=(const Variant &p_variant) { void Variant::operator=(const Variant &p_variant) {
reference(p_variant); if (this == &p_variant)
return;
if (type != p_variant.type) {
reference(p_variant);
return;
}
switch (p_variant.type) {
case NIL: {
// none
} break;
// atomic types
case BOOL: {
_data._bool = p_variant._data._bool;
} break;
case INT: {
_data._int = p_variant._data._int;
} break;
case REAL: {
_data._real = p_variant._data._real;
} break;
case STRING: {
*reinterpret_cast<String *>(_data._mem) = *reinterpret_cast<const String *>(p_variant._data._mem);
} break;
// math types
case VECTOR2: {
*reinterpret_cast<Vector2 *>(_data._mem) = *reinterpret_cast<const Vector2 *>(p_variant._data._mem);
} break;
case RECT2: {
*reinterpret_cast<Rect2 *>(_data._mem) = *reinterpret_cast<const Rect2 *>(p_variant._data._mem);
} break;
case TRANSFORM2D: {
*_data._transform2d = *(p_variant._data._transform2d);
} break;
case VECTOR3: {
*reinterpret_cast<Vector3 *>(_data._mem) = *reinterpret_cast<const Vector3 *>(p_variant._data._mem);
} break;
case PLANE: {
*reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem);
} break;
case RECT3: {
*_data._rect3 = *(p_variant._data._rect3);
} break;
case QUAT: {
*reinterpret_cast<Quat *>(_data._mem) = *reinterpret_cast<const Quat *>(p_variant._data._mem);
} break;
case BASIS: {
*_data._basis = *(p_variant._data._basis);
} break;
case TRANSFORM: {
*_data._transform = *(p_variant._data._transform);
} break;
// misc types
case COLOR: {
*reinterpret_cast<Color *>(_data._mem) = *reinterpret_cast<const Color *>(p_variant._data._mem);
} break;
case _RID: {
*reinterpret_cast<RID *>(_data._mem) = *reinterpret_cast<const RID *>(p_variant._data._mem);
} break;
case OBJECT: {
*reinterpret_cast<ObjData *>(_data._mem) = p_variant._get_obj();
} break;
case NODE_PATH: {
*reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem);
} break;
case DICTIONARY: {
*reinterpret_cast<Dictionary *>(_data._mem) = *reinterpret_cast<const Dictionary *>(p_variant._data._mem);
} break;
case ARRAY: {
*reinterpret_cast<Array *>(_data._mem) = *reinterpret_cast<const Array *>(p_variant._data._mem);
} break;
// arrays
case POOL_BYTE_ARRAY: {
*reinterpret_cast<PoolVector<uint8_t> *>(_data._mem) = *reinterpret_cast<const PoolVector<uint8_t> *>(p_variant._data._mem);
} break;
case POOL_INT_ARRAY: {
*reinterpret_cast<PoolVector<int> *>(_data._mem) = *reinterpret_cast<const PoolVector<int> *>(p_variant._data._mem);
} break;
case POOL_REAL_ARRAY: {
*reinterpret_cast<PoolVector<real_t> *>(_data._mem) = *reinterpret_cast<const PoolVector<real_t> *>(p_variant._data._mem);
} break;
case POOL_STRING_ARRAY: {
*reinterpret_cast<PoolVector<String> *>(_data._mem) = *reinterpret_cast<const PoolVector<String> *>(p_variant._data._mem);
} break;
case POOL_VECTOR2_ARRAY: {
*reinterpret_cast<PoolVector<Vector2> *>(_data._mem) = *reinterpret_cast<const PoolVector<Vector2> *>(p_variant._data._mem);
} break;
case POOL_VECTOR3_ARRAY: {
*reinterpret_cast<PoolVector<Vector3> *>(_data._mem) = *reinterpret_cast<const PoolVector<Vector3> *>(p_variant._data._mem);
} break;
case POOL_COLOR_ARRAY: {
*reinterpret_cast<PoolVector<Color> *>(_data._mem) = *reinterpret_cast<const PoolVector<Color> *>(p_variant._data._mem);
} break;
default: {}
}
} }
Variant::Variant(const IP_Address &p_address) { Variant::Variant(const IP_Address &p_address) {