SImplify capacity presetting for Dictionary to handle memory slack scale internally as suers care about items count only

This commit is contained in:
Wojtek Figat
2025-01-16 17:42:01 +01:00
parent 6111f67e33
commit 1497acef58
9 changed files with 26 additions and 25 deletions

View File

@@ -158,7 +158,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
LOG(Info, "Loading incremental build cooking cache (entries count: {0})", entriesCount); LOG(Info, "Loading incremental build cooking cache (entries count: {0})", entriesCount);
file->ReadBytes(&Settings, sizeof(Settings)); file->ReadBytes(&Settings, sizeof(Settings));
Entries.EnsureCapacity(Math::RoundUpToPowerOf2(static_cast<int32>(entriesCount * 3.0f))); Entries.EnsureCapacity(entriesCount);
Array<Pair<String, DateTime>> fileDependencies; Array<Pair<String, DateTime>> fileDependencies;
for (int32 i = 0; i < entriesCount; i++) for (int32 i = 0; i < entriesCount; i++)

View File

@@ -262,7 +262,7 @@ bool Animation::SaveTimeline(BytesContainer& data)
Events.Clear(); Events.Clear();
NestedAnims.Clear(); NestedAnims.Clear();
Dictionary<int32, int32> animationChannelTrackIndexToChannelIndex; Dictionary<int32, int32> animationChannelTrackIndexToChannelIndex;
animationChannelTrackIndexToChannelIndex.EnsureCapacity(tracksCount * 3); animationChannelTrackIndexToChannelIndex.EnsureCapacity(tracksCount);
for (int32 trackIndex = 0; trackIndex < tracksCount; trackIndex++) for (int32 trackIndex = 0; trackIndex < tracksCount; trackIndex++)
{ {
const byte trackType = stream.ReadByte(); const byte trackType = stream.ReadByte();

View File

@@ -407,7 +407,7 @@ public:
Compact(); Compact();
// Ensure to have enough memory for the next item (in case of new element insertion) // Ensure to have enough memory for the next item (in case of new element insertion)
EnsureCapacity((_elementsCount + 1) * DICTIONARY_DEFAULT_SLACK_SCALE + _deletedCount); EnsureCapacity(_elementsCount + 1 + _deletedCount);
// Find location of the item or place to insert it // Find location of the item or place to insert it
FindPositionResult pos; FindPositionResult pos;
@@ -592,10 +592,11 @@ public:
/// <summary> /// <summary>
/// Ensures that collection has given capacity. /// Ensures that collection has given capacity.
/// </summary> /// </summary>
/// <param name="minCapacity">The minimum required capacity.</param> /// <param name="minCapacity">The minimum required items capacity.</param>
/// <param name="preserveContents">True if preserve collection data when changing its size, otherwise collection after resize will be empty.</param> /// <param name="preserveContents">True if preserve collection data when changing its size, otherwise collection after resize will be empty.</param>
void EnsureCapacity(int32 minCapacity, const bool preserveContents = true) void EnsureCapacity(int32 minCapacity, const bool preserveContents = true)
{ {
minCapacity *= DICTIONARY_DEFAULT_SLACK_SCALE;
if (_size >= minCapacity) if (_size >= minCapacity)
return; return;
int32 capacity = _allocation.CalculateCapacityGrow(_size, minCapacity); int32 capacity = _allocation.CalculateCapacityGrow(_size, minCapacity);
@@ -806,7 +807,7 @@ public:
{ {
// TODO: if both key and value are POD types then use raw memory copy for buckets // TODO: if both key and value are POD types then use raw memory copy for buckets
Clear(); Clear();
EnsureCapacity(other.Capacity(), false); SetCapacity(other.Capacity(), false);
for (Iterator i = other.Begin(); i != other.End(); ++i) for (Iterator i = other.Begin(); i != other.End(); ++i)
Add(i); Add(i);
} }
@@ -939,7 +940,7 @@ private:
Compact(); Compact();
// Ensure to have enough memory for the next item (in case of new element insertion) // Ensure to have enough memory for the next item (in case of new element insertion)
EnsureCapacity((_elementsCount + 1) * DICTIONARY_DEFAULT_SLACK_SCALE + _deletedCount); EnsureCapacity(_elementsCount + 1 + _deletedCount);
// Find location of the item or place to insert it // Find location of the item or place to insert it
FindPositionResult pos; FindPositionResult pos;

View File

@@ -256,7 +256,7 @@ void PrefabInstanceData::SerializePrefabInstances(PrefabInstancesData& prefabIns
} }
// Build acceleration table // Build acceleration table
instance.PrefabInstanceIdToDataIndex.EnsureCapacity(sceneObjects->Count() * 4); instance.PrefabInstanceIdToDataIndex.EnsureCapacity(sceneObjects->Count());
for (int32 i = 0; i < sceneObjects->Count(); i++) for (int32 i = 0; i < sceneObjects->Count(); i++)
{ {
SceneObject* obj = sceneObjects.Value->At(i); SceneObject* obj = sceneObjects.Value->At(i);
@@ -296,7 +296,7 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI
SceneQuery::GetAllSerializableSceneObjects(instance.TargetActor, *sceneObjects.Value); SceneQuery::GetAllSerializableSceneObjects(instance.TargetActor, *sceneObjects.Value);
int32 existingObjectsCount = sceneObjects->Count(); int32 existingObjectsCount = sceneObjects->Count();
modifier->IdsMapping.EnsureCapacity((existingObjectsCount + newPrefabObjectIds.Count()) * 4); modifier->IdsMapping.EnsureCapacity((existingObjectsCount + newPrefabObjectIds.Count()));
// Map prefab objects to the prefab instance objects // Map prefab objects to the prefab instance objects
for (int32 i = 0; i < existingObjectsCount; i++) for (int32 i = 0; i < existingObjectsCount; i++)
@@ -561,7 +561,7 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI
// Build cache data // Build cache data
IdToDataLookupType prefabObjectIdToDiffData; IdToDataLookupType prefabObjectIdToDiffData;
prefabObjectIdToDiffData.EnsureCapacity(defaultInstanceData.Size() * 3); prefabObjectIdToDiffData.EnsureCapacity(defaultInstanceData.Size());
for (int32 i = 0; i < sceneObjects->Count(); i++) for (int32 i = 0; i < sceneObjects->Count(); i++)
{ {
SceneObject* obj = sceneObjects.Value->At(i); SceneObject* obj = sceneObjects.Value->At(i);
@@ -760,8 +760,8 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
rapidjson_flax::Document diffDataDocument; rapidjson_flax::Document diffDataDocument;
Dictionary<Guid, int32> diffPrefabObjectIdToDataIndex; // Maps Prefab Object Id -> Actor Data index in diffDataDocument json array (for actors/scripts to modify prefab) Dictionary<Guid, int32> diffPrefabObjectIdToDataIndex; // Maps Prefab Object Id -> Actor Data index in diffDataDocument json array (for actors/scripts to modify prefab)
Dictionary<Guid, int32> newPrefabInstanceIdToDataIndex; // Maps Prefab Instance Id -> Actor Data index in diffDataDocument json array (for new actors/scripts to add to prefab), maps to -1 for scripts Dictionary<Guid, int32> newPrefabInstanceIdToDataIndex; // Maps Prefab Instance Id -> Actor Data index in diffDataDocument json array (for new actors/scripts to add to prefab), maps to -1 for scripts
diffPrefabObjectIdToDataIndex.EnsureCapacity(ObjectsCount * 4); diffPrefabObjectIdToDataIndex.EnsureCapacity(ObjectsCount);
newPrefabInstanceIdToDataIndex.EnsureCapacity(ObjectsCount * 4); newPrefabInstanceIdToDataIndex.EnsureCapacity(ObjectsCount);
{ {
// Parse json to DOM document // Parse json to DOM document
{ {
@@ -813,7 +813,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
// Change object ids to match the prefab objects ids (helps with linking references in scripts) // Change object ids to match the prefab objects ids (helps with linking references in scripts)
Dictionary<Guid, Guid> objectInstanceIdToPrefabObjectId; Dictionary<Guid, Guid> objectInstanceIdToPrefabObjectId;
objectInstanceIdToPrefabObjectId.EnsureCapacity(ObjectsCount * 3); objectInstanceIdToPrefabObjectId.EnsureCapacity(ObjectsCount);
i = 0; i = 0;
for (auto it = array.Begin(); it != array.End(); ++it, i++) for (auto it = array.Begin(); it != array.End(); ++it, i++)
{ {
@@ -843,7 +843,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping); Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping);
// Generate new IDs for the added objects (objects in prefab has to have a unique Ids, other than the targetActor instance objects to prevent Id collisions) // Generate new IDs for the added objects (objects in prefab has to have a unique Ids, other than the targetActor instance objects to prevent Id collisions)
newPrefabInstanceIdToPrefabObjectId.EnsureCapacity(newPrefabInstanceIdToDataIndex.Count() * 4); newPrefabInstanceIdToPrefabObjectId.EnsureCapacity(newPrefabInstanceIdToDataIndex.Count());
for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i) for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i)
{ {
const auto prefabObjectId = Guid::New(); const auto prefabObjectId = Guid::New();
@@ -1175,9 +1175,9 @@ bool Prefab::UpdateInternal(const Array<SceneObject*>& defaultInstanceObjects, r
const int32 objectsCount = Data->GetArray().Size(); const int32 objectsCount = Data->GetArray().Size();
if (objectsCount <= 0) if (objectsCount <= 0)
return true; return true;
ObjectsIds.EnsureCapacity(objectsCount * 2); ObjectsIds.EnsureCapacity(objectsCount);
NestedPrefabs.EnsureCapacity(objectsCount); NestedPrefabs.EnsureCapacity(objectsCount);
ObjectsDataCache.EnsureCapacity(objectsCount * 3); ObjectsDataCache.EnsureCapacity(objectsCount);
const auto& data = *Data; const auto& data = *Data;
for (int32 objectIndex = 0; objectIndex < objectsCount; objectIndex++) for (int32 objectIndex = 0; objectIndex < objectsCount; objectIndex++)
{ {
@@ -1197,7 +1197,7 @@ bool Prefab::UpdateInternal(const Array<SceneObject*>& defaultInstanceObjects, r
{ {
if (prefabId == _id) if (prefabId == _id)
{ {
LOG(Error, "Circural reference in prefab."); LOG(Error, "Circular reference in prefab.");
continue; continue;
} }

View File

@@ -128,8 +128,8 @@ Asset::LoadResult Prefab::loadAsset()
} }
// Allocate memory for objects // Allocate memory for objects
ObjectsIds.EnsureCapacity(objectsCount * 2); ObjectsIds.EnsureCapacity(objectsCount);
ObjectsDataCache.EnsureCapacity(objectsCount * 3); ObjectsDataCache.EnsureCapacity(objectsCount);
// Find serialized object ids (actors and scripts), they are used later for IDs mapping on prefab spawning via PrefabManager // Find serialized object ids (actors and scripts), they are used later for IDs mapping on prefab spawning via PrefabManager
const auto& data = *Data; const auto& data = *Data;
@@ -157,7 +157,7 @@ Asset::LoadResult Prefab::loadAsset()
{ {
if (prefabId == _id) if (prefabId == _id)
{ {
LOG(Error, "Circural reference in prefab."); LOG(Error, "Circular reference in prefab.");
return LoadResult::InvalidData; return LoadResult::InvalidData;
} }

View File

@@ -111,8 +111,8 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, const Transform& transform, Ac
sceneObjects->Resize(dataCount); sceneObjects->Resize(dataCount);
CollectionPoolCache<ISerializeModifier, Cache::ISerializeModifierClearCallback>::ScopeCache modifier = Cache::ISerializeModifier.Get(); CollectionPoolCache<ISerializeModifier, Cache::ISerializeModifierClearCallback>::ScopeCache modifier = Cache::ISerializeModifier.Get();
modifier->EngineBuild = prefab->DataEngineBuild; modifier->EngineBuild = prefab->DataEngineBuild;
modifier->IdsMapping.EnsureCapacity(prefab->ObjectsIds.Count() * 4);
for (int32 i = 0; i < prefab->ObjectsIds.Count(); i++) for (int32 i = 0; i < prefab->ObjectsIds.Count(); i++)
modifier->IdsMapping.EnsureCapacity(prefab->ObjectsIds.Count());
{ {
modifier->IdsMapping.Add(prefab->ObjectsIds[i], Guid::New()); modifier->IdsMapping.Add(prefab->ObjectsIds[i], Guid::New());
} }
@@ -352,7 +352,7 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat
// Randomize the objects ids (prevent overlapping of the prefab instance objects ids and the prefab objects ids) // Randomize the objects ids (prevent overlapping of the prefab instance objects ids and the prefab objects ids)
Dictionary<Guid, Guid> objectInstanceIdToPrefabObjectId; Dictionary<Guid, Guid> objectInstanceIdToPrefabObjectId;
objectInstanceIdToPrefabObjectId.EnsureCapacity(sceneObjects->Count() * 3); objectInstanceIdToPrefabObjectId.EnsureCapacity(sceneObjects->Count());
if (targetActor->HasParent()) if (targetActor->HasParent())
{ {
// Unlink from parent actor // Unlink from parent actor

View File

@@ -88,7 +88,7 @@ bool SceneCSGData::TryGetSurfaceData(const Guid& brushId, int32 brushSurfaceInde
// Invalid data // Invalid data
return false; return false;
} }
DataBrushLocations.EnsureCapacity((int32)(brushesCount * 4.0f)); DataBrushLocations.EnsureCapacity(brushesCount);
for (int32 i = 0; i < brushesCount; i++) for (int32 i = 0; i < brushesCount; i++)
{ {
Guid id; Guid id;

View File

@@ -931,7 +931,7 @@ void ManagedBinaryModule::OnLoaded(MAssembly* assembly)
const auto& classes = assembly->GetClasses(); const auto& classes = assembly->GetClasses();
// Cache managed types information // Cache managed types information
ClassToTypeIndex.EnsureCapacity(Types.Count() * 4); ClassToTypeIndex.EnsureCapacity(Types.Count());
for (int32 typeIndex = 0; typeIndex < Types.Count(); typeIndex++) for (int32 typeIndex = 0; typeIndex < Types.Count(); typeIndex++)
{ {
ScriptingType& type = Types[typeIndex]; ScriptingType& type = Types[typeIndex];

View File

@@ -649,7 +649,7 @@ namespace Serialization
{ {
const auto& streamArray = stream.GetArray(); const auto& streamArray = stream.GetArray();
const int32 size = streamArray.Size(); const int32 size = streamArray.Size();
v.EnsureCapacity(size * 3); v.EnsureCapacity(size);
for (int32 i = 0; i < size; i++) for (int32 i = 0; i < size; i++)
{ {
auto& streamItem = streamArray[i]; auto& streamItem = streamArray[i];
@@ -666,7 +666,7 @@ namespace Serialization
else if (stream.IsObject()) else if (stream.IsObject())
{ {
const int32 size = stream.MemberCount(); const int32 size = stream.MemberCount();
v.EnsureCapacity(size * 3); v.EnsureCapacity(size);
for (auto i = stream.MemberBegin(); i != stream.MemberEnd(); ++i) for (auto i = stream.MemberBegin(); i != stream.MemberEnd(); ++i)
{ {
KeyType key; KeyType key;