Parcourir la source

Entity中SortedDictionary key是type的fullname,string做key速度太慢了,比使用Dictionary慢了30倍。
改成key是type的fullname做longhash,longhash缓存起来
这样比使用Dictionary慢了4倍,再搭配EntityRef已经可用了。

CodeTypesHelper.GetLongHashCode 帧同步项目需要type的确定性hash,如果不是帧同步项目,
可以直接返回type.GetHashCode(),速度可以再加快1/3

tanghai il y a 2 ans
Parent
commit
508cd8fb05

+ 1 - 1
DotNet/Loader/CodeLoader.cs

@@ -49,7 +49,7 @@ namespace ET
 			
             CodeTypes codeTypes = World.Instance.AddSingleton<CodeTypes, Assembly[]>(new[] { typeof (World).Assembly, typeof(Init).Assembly, this.assembly, hotfixAssembly });
 
-            codeTypes.CreateCodeSingleton();
+            codeTypes.CreateCode();
             Log.Debug($"reload dll finish!");
         }
     }

+ 2 - 2
Unity/Assets/Scripts/Core/DoubleMap.cs

@@ -5,8 +5,8 @@ namespace ET
 {
 	public class DoubleMap<K, V>
 	{
-		private readonly Dictionary<K, V> kv = new Dictionary<K, V>();
-		private readonly Dictionary<V, K> vk = new Dictionary<V, K>();
+		private readonly Dictionary<K, V> kv = new();
+		private readonly Dictionary<V, K> vk = new();
 
 		public DoubleMap()
 		{

+ 18 - 18
Unity/Assets/Scripts/Core/Entity/Entity.cs

@@ -327,7 +327,7 @@ namespace ET
                         foreach (Entity component in this.componentsDB)
                         {
                             component.IsComponent = true;
-                            this.Components.Add(component.GetType().FullName, component);
+                            this.Components.Add(component.GetType().GetLongHashCode(), component);
                             component.parent = this;
                         }
                     }
@@ -410,14 +410,14 @@ namespace ET
         private List<Entity> componentsDB;
 
         [BsonIgnore]
-        private SortedDictionary<string, Entity> components;
+        private SortedDictionary<long, Entity> components;
 
         [BsonIgnore]
-        public SortedDictionary<string, Entity> Components
+        public SortedDictionary<long, Entity> Components
         {
             get
             {
-                return this.components ??= ObjectPool.Instance.Fetch<SortedDictionary<string, Entity>>();
+                return this.components ??= ObjectPool.Instance.Fetch<SortedDictionary<long, Entity>>();
             }
         }
 
@@ -477,7 +477,7 @@ namespace ET
             // 清理Component
             if (this.components != null)
             {
-                foreach (KeyValuePair<string, Entity> kv in this.components)
+                foreach (var kv in this.components)
                 {
                     kv.Value.Dispose();
                 }
@@ -532,7 +532,7 @@ namespace ET
 
         private void AddToComponents(Entity component)
         {
-            this.Components.Add(component.GetType().FullName, component);
+            this.Components.Add(component.GetType().GetLongHashCode(), component);
         }
 
         private void RemoveFromComponents(Entity component)
@@ -542,7 +542,7 @@ namespace ET
                 return;
             }
 
-            this.components.Remove(component.GetType().FullName);
+            this.components.Remove(component.GetType().GetLongHashCode());
 
             if (this.components.Count == 0)
             {
@@ -593,7 +593,7 @@ namespace ET
             Type type = typeof (K);
             
             Entity c;
-            if (!this.components.TryGetValue(type.FullName, out c))
+            if (!this.components.TryGetValue(type.GetLongHashCode(), out c))
             {
                 return;
             }
@@ -615,7 +615,7 @@ namespace ET
             }
 
             Entity c;
-            if (!this.components.TryGetValue(component.GetType().FullName, out c))
+            if (!this.components.TryGetValue(component.GetType().GetLongHashCode(), out c))
             {
                 return;
             }
@@ -637,7 +637,7 @@ namespace ET
             }
 
             Entity c;
-            if (!this.components.TryGetValue(type.FullName, out c))
+            if (!this.components.TryGetValue(type.GetLongHashCode(), out c))
             {
                 return;
             }
@@ -660,7 +660,7 @@ namespace ET
             }
             
             Entity component;
-            if (!this.components.TryGetValue(typeof (K).FullName, out component))
+            if (!this.components.TryGetValue(typeof (K).GetLongHashCode(), out component))
             {
                 return default;
             }
@@ -683,7 +683,7 @@ namespace ET
             }
             
             Entity component;
-            if (!this.components.TryGetValue(type.FullName, out component))
+            if (!this.components.TryGetValue(type.GetLongHashCode(), out component))
             {
                 return null;
             }
@@ -713,7 +713,7 @@ namespace ET
         public Entity AddComponent(Entity component)
         {
             Type type = component.GetType();
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }
@@ -725,7 +725,7 @@ namespace ET
 
         public Entity AddComponent(Type type, bool isFromPool = false)
         {
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }
@@ -742,7 +742,7 @@ namespace ET
         public K AddComponentWithId<K>(long id, bool isFromPool = false) where K : Entity, IAwake, new()
         {
             Type type = typeof (K);
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }
@@ -759,7 +759,7 @@ namespace ET
         public K AddComponentWithId<K, P1>(long id, P1 p1, bool isFromPool = false) where K : Entity, IAwake<P1>, new()
         {
             Type type = typeof (K);
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }
@@ -776,7 +776,7 @@ namespace ET
         public K AddComponentWithId<K, P1, P2>(long id, P1 p1, P2 p2, bool isFromPool = false) where K : Entity, IAwake<P1, P2>, new()
         {
             Type type = typeof (K);
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }
@@ -793,7 +793,7 @@ namespace ET
         public K AddComponentWithId<K, P1, P2, P3>(long id, P1 p1, P2 p2, P3 p3, bool isFromPool = false) where K : Entity, IAwake<P1, P2, P3>, new()
         {
             Type type = typeof (K);
-            if (this.components != null && this.components.ContainsKey(type.FullName))
+            if (this.components != null && this.components.ContainsKey(type.GetLongHashCode()))
             {
                 throw new Exception($"entity already has component: {type.FullName}");
             }

+ 19 - 0
Unity/Assets/Scripts/Core/Map.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+namespace ET
+{
+    public class Map<T, K>: SortedDictionary<T, K>, IDisposable
+    {
+        public static Map<T, K> Create()
+        {
+            return ObjectPool.Instance.Fetch(typeof (Map<T, K>)) as Map<T, K>;
+        }
+
+        public void Dispose()
+        {
+            this.Clear();
+            ObjectPool.Instance.Recycle(this);
+        }
+    }
+}

+ 11 - 0
Unity/Assets/Scripts/Core/Map.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 289937f851b049744aebb761639041dc
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 27 - 1
Unity/Assets/Scripts/Core/World/Module/Code/CodeTypes.cs

@@ -4,10 +4,21 @@ using System;
 
 namespace ET
 {
+    public static class CodeTypesHelper
+    {
+        public static long GetLongHashCode(this Type type)
+        {
+            // 帧同步项目需要type的确定性hash,如果不是帧同步项目,这里可以直接返回type.GetHashCode()
+            //return type.GetHashCode(); // 这样速度再快1/3
+            return CodeTypes.Instance.GetHashByType(type);
+        }
+    }
+    
     public class CodeTypes: Singleton<CodeTypes>, ISingletonAwake<Assembly[]>
     {
         private readonly Dictionary<string, Type> allTypes = new();
         private readonly UnOrderMultiMapSet<Type, Type> types = new();
+        private readonly DoubleMap<Type, long> entityTypeHash = new();
 
         public void Awake(Assembly[] assemblies)
         {
@@ -28,6 +39,11 @@ namespace ET
                 {
                     this.types.Add(o.GetType(), type);
                 }
+
+                if (typeof(Entity).IsAssignableFrom(type))
+                {
+                    this.entityTypeHash.Add(type, type.FullName.GetLongHashCode());
+                }
             }
         }
 
@@ -51,7 +67,17 @@ namespace ET
             return this.allTypes[typeName];
         }
         
-        public void CreateCodeSingleton()
+        public Type GetTypeByHash(long hash)
+        {
+            return this.entityTypeHash.GetKeyByValue(hash);
+        }
+        
+        public long GetHashByType(Type type)
+        {
+            return this.entityTypeHash.GetValueByKey(type);
+        }
+        
+        public void CreateCode()
         {
             var hashSet = this.GetTypes(typeof (CodeAttribute));
             foreach (Type type in hashSet)

+ 1 - 0
Unity/Assets/Scripts/HotfixView/Client/Demo/EntryEvent3_InitClient.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.IO;
 
 namespace ET.Client

+ 1 - 1
Unity/Assets/Scripts/Loader/CodeLoader.cs

@@ -104,7 +104,7 @@ namespace ET
 			Assembly hotfixAssembly = this.LoadHotfix();
 
 			CodeTypes codeTypes = World.Instance.AddSingleton<CodeTypes, Assembly[]>(new []{typeof (World).Assembly, typeof(Init).Assembly, this.assembly, hotfixAssembly});
-			codeTypes.CreateCodeSingleton();
+			codeTypes.CreateCode();
 
 			Log.Debug($"reload dll finish!");
 		}

+ 1 - 1
Unity/Assets/Scripts/Model/Share/Entry.cs

@@ -42,7 +42,7 @@
             World.Instance.AddSingleton<LogMsg>();
             
             // 创建需要reload的code singleton
-            CodeTypes.Instance.CreateCodeSingleton();
+            CodeTypes.Instance.CreateCode();
 
             await FiberManager.Instance.Create(SchedulerType.Main, ConstFiberId.Main, 0, SceneType.Main, "");
         }