Browse Source

Changed unordered_map -> vector in the binary restore functions to reduce the amount of allocations

Jorrit Rouwe 3 years ago
parent
commit
e5aa8fc3dc

+ 4 - 4
Jolt/Physics/Body/BodyCreationSettings.cpp

@@ -217,8 +217,7 @@ BodyCreationSettings::BCSResult BodyCreationSettings::sRestoreWithChildren(Strea
 	if (group_filter_id != ~uint32(0))
 	if (group_filter_id != ~uint32(0))
 	{
 	{
 		// Check if it already exists
 		// Check if it already exists
-		IDToGroupFilterMap::const_iterator group_filter_it = ioGroupFilterMap.find(group_filter_id);
-		if (group_filter_it == ioGroupFilterMap.end())
+		if (group_filter_id >= ioGroupFilterMap.size())
 		{
 		{
 			// New group filter, restore it
 			// New group filter, restore it
 			GroupFilter::GroupFilterResult group_filter_result = GroupFilter::sRestoreFromBinaryState(inStream);
 			GroupFilter::GroupFilterResult group_filter_result = GroupFilter::sRestoreFromBinaryState(inStream);
@@ -228,12 +227,13 @@ BodyCreationSettings::BCSResult BodyCreationSettings::sRestoreWithChildren(Strea
 				return result;
 				return result;
 			}
 			}
 			group_filter = group_filter_result.Get();
 			group_filter = group_filter_result.Get();
-			ioGroupFilterMap[group_filter_id] = group_filter;
+			JPH_ASSERT(group_filter_id == ioGroupFilterMap.size());
+			ioGroupFilterMap.push_back(group_filter);
 		}
 		}
 		else
 		else
 		{
 		{
 			// Existing group filter
 			// Existing group filter
-			group_filter = group_filter_it->second;
+			group_filter = ioGroupFilterMap[group_filter_id];
 		}
 		}
 	}
 	}
 
 

+ 1 - 1
Jolt/Physics/Body/BodyCreationSettings.h

@@ -58,7 +58,7 @@ public:
 	void					RestoreBinaryState(StreamIn &inStream);
 	void					RestoreBinaryState(StreamIn &inStream);
 
 
 	using GroupFilterToIDMap = unordered_map<const GroupFilter *, uint32>;
 	using GroupFilterToIDMap = unordered_map<const GroupFilter *, uint32>;
-	using IDToGroupFilterMap = unordered_map<uint32, RefConst<GroupFilter>>;
+	using IDToGroupFilterMap = vector<RefConst<GroupFilter>>;
 	using ShapeToIDMap = Shape::ShapeToIDMap;
 	using ShapeToIDMap = Shape::ShapeToIDMap;
 	using IDToShapeMap = Shape::IDToShapeMap;
 	using IDToShapeMap = Shape::IDToShapeMap;
 	using MaterialToIDMap = Shape::MaterialToIDMap;
 	using MaterialToIDMap = Shape::MaterialToIDMap;

+ 8 - 8
Jolt/Physics/Collision/Shape/Shape.cpp

@@ -188,10 +188,9 @@ Shape::ShapeResult Shape::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap
 	}
 	}
 
 
 	// Check if we already read this shape
 	// Check if we already read this shape
-	IDToShapeMap::const_iterator shape_it = ioShapeMap.find(shape_id);
-	if (shape_it != ioShapeMap.end())
+	if (shape_id < ioShapeMap.size())
 	{
 	{
-		result.Set(shape_it->second);
+		result.Set(ioShapeMap[shape_id]);
 		return result;
 		return result;
 	}
 	}
 
 
@@ -199,7 +198,8 @@ Shape::ShapeResult Shape::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap
 	result = sRestoreFromBinaryState(inStream);
 	result = sRestoreFromBinaryState(inStream);
 	if (result.HasError())
 	if (result.HasError())
 		return result;
 		return result;
-	ioShapeMap[shape_id] = result.Get();
+	JPH_ASSERT(ioShapeMap.size() == shape_id); // Assert that this is the next ID in the map
+	ioShapeMap.push_back(result.Get());
 
 
 	// Read the sub shapes
 	// Read the sub shapes
 	size_t len;
 	size_t len;
@@ -237,8 +237,7 @@ Shape::ShapeResult Shape::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap
 		// Check nullptr
 		// Check nullptr
 		if (material_id != ~uint32(0))
 		if (material_id != ~uint32(0))
 		{
 		{
-			IDToMaterialMap::const_iterator material_it = ioMaterialMap.find(material_id);
-			if (material_it == ioMaterialMap.end())
+			if (material_id >= ioMaterialMap.size())
 			{
 			{
 				// New material, restore material
 				// New material, restore material
 				PhysicsMaterial::PhysicsMaterialResult material_result = PhysicsMaterial::sRestoreFromBinaryState(inStream);
 				PhysicsMaterial::PhysicsMaterialResult material_result = PhysicsMaterial::sRestoreFromBinaryState(inStream);
@@ -248,12 +247,13 @@ Shape::ShapeResult Shape::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap
 					return result;
 					return result;
 				}
 				}
 				material = material_result.Get();
 				material = material_result.Get();
-				ioMaterialMap[material_id] = material;
+				JPH_ASSERT(material_id == ioMaterialMap.size());
+				ioMaterialMap.push_back(material);
 			}
 			}
 			else
 			else
 			{
 			{
 				// Existing material
 				// Existing material
-				material = material_it->second;
+				material = ioMaterialMap[material_id];
 			}
 			}
 		}
 		}
 
 

+ 2 - 2
Jolt/Physics/Collision/Shape/Shape.h

@@ -252,8 +252,8 @@ public:
 
 
 	using ShapeToIDMap = unordered_map<const Shape *, uint32>;
 	using ShapeToIDMap = unordered_map<const Shape *, uint32>;
 	using MaterialToIDMap = unordered_map<const PhysicsMaterial *, uint32>;
 	using MaterialToIDMap = unordered_map<const PhysicsMaterial *, uint32>;
-	using IDToShapeMap = unordered_map<uint32, Ref<Shape>>;
-	using IDToMaterialMap = unordered_map<uint32, Ref<PhysicsMaterial>>;
+	using IDToShapeMap = vector<Ref<Shape>>;
+	using IDToMaterialMap = vector<Ref<PhysicsMaterial>>;
 
 
 	/// Save this shape, all its children and its materials. Pass in an empty map in ioShapeMap / ioMaterialMap or reuse the same map while saving multiple shapes to the same stream in order to avoid writing duplicates.
 	/// Save this shape, all its children and its materials. Pass in an empty map in ioShapeMap / ioMaterialMap or reuse the same map while saving multiple shapes to the same stream in order to avoid writing duplicates.
 	void							SaveWithChildren(StreamOut &inStream, ShapeToIDMap &ioShapeMap, MaterialToIDMap &ioMaterialMap) const;
 	void							SaveWithChildren(StreamOut &inStream, ShapeToIDMap &ioShapeMap, MaterialToIDMap &ioMaterialMap) const;

+ 5 - 0
Jolt/Physics/PhysicsScene.cpp

@@ -71,6 +71,11 @@ PhysicsScene::PhysicsSceneResult PhysicsScene::sRestoreFromBinaryState(StreamIn
 	BodyCreationSettings::IDToMaterialMap id_to_material;
 	BodyCreationSettings::IDToMaterialMap id_to_material;
 	BodyCreationSettings::IDToGroupFilterMap id_to_group_filter;
 	BodyCreationSettings::IDToGroupFilterMap id_to_group_filter;
 
 
+	// Reserve some memory to avoid frequent reallocations
+	id_to_shape.reserve(1024);
+	id_to_material.reserve(128);
+	id_to_group_filter.reserve(128);
+
 	// Read bodies
 	// Read bodies
 	uint32 len = 0;
 	uint32 len = 0;
 	inStream.Read(len);
 	inStream.Read(len);

+ 5 - 0
Jolt/Physics/Ragdoll/Ragdoll.cpp

@@ -220,6 +220,11 @@ RagdollSettings::RagdollResult RagdollSettings::sRestoreFromBinaryState(StreamIn
 	BodyCreationSettings::IDToMaterialMap id_to_material;
 	BodyCreationSettings::IDToMaterialMap id_to_material;
 	BodyCreationSettings::IDToGroupFilterMap id_to_group_filter;
 	BodyCreationSettings::IDToGroupFilterMap id_to_group_filter;
 
 
+	// Reserve some memory to avoid frequent reallocations
+	id_to_shape.reserve(1024);
+	id_to_material.reserve(128);
+	id_to_group_filter.reserve(128);
+
 	// Read parts
 	// Read parts
 	uint32 len = 0;
 	uint32 len = 0;
 	inStream.Read(len);
 	inStream.Read(len);