Performance is not affected. The test below take the same time with both old and new version (75++5 ms for Debug, 10-+0.5 ms for Release). I didn’t test metadata-related changes because they have very limited area.
Code
#include <Urho3D/Scene/Serializable.h>
#include <Urho3D/IO/VectorBuffer.h>
#include <Urho3D/Core/StringUtils.h>
#include <chrono>
using namespace Urho3D;
#define URHO3D_NEW_ATTRIBUTE(name, typeName, variable, defaultValue, mode) URHO3D_ACCESSOR_ATTRIBUTE_FREE(name, [](const ClassName* classPtr) -> typename AttributeTrait<typeName >::ReturnType { return classPtr->variable; }, [](ClassName* classPtr, typename AttributeTrait<typeName >::ParameterType value) { classPtr->variable = value; }, typeName, defaultValue, mode)
#undef URHO3D_ATTRIBUTE
#define URHO3D_ATTRIBUTE(name, typeName, variable, defaultValue, mode) URHO3D_NEW_ATTRIBUTE(name, typeName, variable, defaultValue, mode)
class TestSerializable : public Serializable
{
URHO3D_OBJECT(TestSerializable, Serializable);
public:
TestSerializable(Context* context) : Serializable(context)
{
bool_ = !!Random(0, 1);
int_ = Random(1, 100);
float_ = Random(1.0f, 100.0f);
string_ = String(Random(1, 100));
vector_ = { Random(1, 100), Random(1, 100), Random(1, 100) };
map_ = { { "1", Random(1, 100) }, { "2", Random(1, 100) }, { "3", Random(1, 100) } };
}
static void RegisterObject(Context* context)
{
context->RegisterFactory<TestSerializable>();
URHO3D_ATTRIBUTE("Bool", bool, bool_, false, AM_DEFAULT);
URHO3D_ATTRIBUTE("Int", int, int_, 0, AM_DEFAULT);
URHO3D_ATTRIBUTE("Float", float, float_, 0.0f, AM_DEFAULT);
URHO3D_ATTRIBUTE("String", String, string_, String::EMPTY, AM_DEFAULT);
URHO3D_ATTRIBUTE("VariantVector", VariantVector, vector_, Variant::emptyVariantVector, AM_DEFAULT);
URHO3D_ATTRIBUTE("VariantMap", VariantMap, map_, Variant::emptyVariantMap, AM_DEFAULT);
}
private:
bool bool_;
int int_;
float float_;
String string_;
VariantVector vector_;
VariantMap map_;
};
size_t Test(Context* context)
{
TestSerializable::RegisterObject(context);
Vector<SharedPtr<TestSerializable>> objects;
for (int i = 0; i < 10000; ++i)
objects.Push(MakeShared<TestSerializable>(context));
VectorBuffer output;
output.Resize(1024 * 1024);
auto t1 = std::chrono::high_resolution_clock::now();
for (TestSerializable* object : objects)
object->Save(output);
auto t2 = std::chrono::high_resolution_clock::now();
size_t us = (size_t)std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count();
File file(context);
file.Open("C:/output.bin", FILE_WRITE);
file.Write(output.GetData(), output.GetSize());
file.Close();
return us;
}
The idea is pretty simple here. Have you heard about “single line -
single declaration” rule in C++? Here is the same situation. Metadata is the declaration of the new variable inside the map, so it shall be placed on its own line.
The same is about variadic SendEvent
: I’d like to put every event parameter on its own line.