Prechádzať zdrojové kódy

优化了下定时器的实现,保存最小时间,不用每次都去MultiMap取最小值

tanghai 7 rokov pred
rodič
commit
7fc9924ed0

+ 0 - 159
Server/Model/Base/MultiMap.cs

@@ -1,159 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace ETModel
-{
-	public class MultiMap<T, K>
-	{
-		private readonly SortedDictionary<T, List<K>> dictionary = new SortedDictionary<T, List<K>>();
-
-		// 重用list
-		private readonly Queue<List<K>> queue = new Queue<List<K>>();
-
-		public SortedDictionary<T, List<K>> GetDictionary()
-		{
-			return this.dictionary;
-		}
-
-		public void Add(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				list = this.FetchList();
-			}
-			list.Add(k);
-			this.dictionary[t] = list;
-		}
-
-		public KeyValuePair<T, List<K>> First()
-		{
-			return this.dictionary.First();
-		}
-
-		public T FirstKey()
-		{
-			return this.dictionary.Keys.First();
-		}
-
-		public int Count
-		{
-			get
-			{
-				return this.dictionary.Count;
-			}
-		}
-
-		private List<K> FetchList()
-		{
-			if (this.queue.Count > 0)
-			{
-				List<K> list = this.queue.Dequeue();
-				list.Clear();
-				return list;
-			}
-			return new List<K>();
-		}
-
-		private void RecycleList(List<K> list)
-		{
-			// 防止暴涨
-			if (this.queue.Count > 100)
-			{
-				return;
-			}
-			list.Clear();
-			this.queue.Enqueue(list);
-		}
-
-		public bool Remove(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return false;
-			}
-			if (!list.Remove(k))
-			{
-				return false;
-			}
-			if (list.Count == 0)
-			{
-				this.RecycleList(list);
-				this.dictionary.Remove(t);
-			}
-			return true;
-		}
-
-		public bool Remove(T t)
-		{
-			List<K> list = null;
-			this.dictionary.TryGetValue(t, out list);
-			if (list != null)
-			{
-				this.RecycleList(list);
-			}
-			return this.dictionary.Remove(t);
-		}
-
-		/// <summary>
-		/// 不返回内部的list,copy一份出来
-		/// </summary>
-		/// <param name="t"></param>
-		/// <returns></returns>
-		public K[] GetAll(T t)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return new K[0];
-			}
-			return list.ToArray();
-		}
-
-		/// <summary>
-		/// 返回内部的list
-		/// </summary>
-		/// <param name="t"></param>
-		/// <returns></returns>
-		public List<K> this[T t]
-		{
-			get
-			{
-				List<K> list;
-				this.dictionary.TryGetValue(t, out list);
-				return list;
-			}
-		}
-
-		public K GetOne(T t)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list != null && list.Count > 0)
-			{
-				return list[0];
-			}
-			return default(K);
-		}
-
-		public bool Contains(T t, K k)
-		{
-			List<K> list;
-			this.dictionary.TryGetValue(t, out list);
-			if (list == null)
-			{
-				return false;
-			}
-			return list.Contains(k);
-		}
-
-		public bool ContainsKey(T t)
-		{
-			return this.dictionary.ContainsKey(t);
-		}
-	}
-}

+ 1 - 0
Server/Model/Server.Model.csproj

@@ -34,6 +34,7 @@
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\StringHelper.cs" Link="Base\Helper\StringHelper.cs" />
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\TimeHelper.cs" Link="Base\Helper\TimeHelper.cs" />
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Helper\ZipHelper.cs" Link="Base\Helper\ZipHelper.cs" />
+    <Compile Include="..\..\Unity\Assets\Scripts\Base\MultiMap.cs" Link="Base\MultiMap.cs" />
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Object\Component.cs" Link="Base\Object\Component.cs" />
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Object\ComponentFactory.cs" Link="Base\Object\ComponentFactory.cs" />
     <Compile Include="..\..\Unity\Assets\Scripts\Base\Object\ComponentWithId.cs" Link="Base\Object\ComponentWithId.cs" />

+ 5 - 4
Unity/Assets/Scripts/Base/MultiMap.cs

@@ -5,13 +5,14 @@ namespace ETModel
 {
 	public class MultiMap<T, K>
 	{
-		// 客户端用SortedList,因为unity用SortedDictionary在取firstkey的时候有gc,再者客户端的插入删除并不多
-		private readonly SortedList<T, List<K>> dictionary = new SortedList<T, List<K>>();
+		private readonly SortedDictionary<T, List<K>> dictionary = new SortedDictionary<T, List<K>>();
 
 		// 重用list
 		private readonly Queue<List<K>> queue = new Queue<List<K>>();
 
-		public SortedList<T, List<K>> GetDictionary()
+		private T firstKey;
+
+		public SortedDictionary<T, List<K>> GetDictionary()
 		{
 			return this.dictionary;
 		}
@@ -35,7 +36,7 @@ namespace ETModel
 
 		public T FirstKey()
 		{
-			return this.dictionary.Keys[0];
+			return this.dictionary.Keys.First();
 		}
 
 		public int Count

+ 41 - 15
Unity/Assets/Scripts/Component/TimerComponent.cs

@@ -29,7 +29,10 @@ namespace ETModel
 		/// </summary>
 		private readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
 
-		private readonly List<long> timeOutId = new List<long>();
+		private readonly List<long> timeOutTime = new List<long>();
+
+		// 记录最小时间,不用每次都去MultiMap取第一个值
+		private long minTime;
 
 		public void Update()
 		{
@@ -40,31 +43,38 @@ namespace ETModel
 
 			long timeNow = TimeHelper.Now();
 
-			timeOutId.Clear();
+			if (timeNow < this.minTime)
+			{
+				return;
+			}
+			
+			this.timeOutTime.Clear();
 
-			while (this.timeId.Count > 0)
+			foreach (KeyValuePair<long,List<long>> kv in this.timeId.GetDictionary())
 			{
-				long k = this.timeId.FirstKey();
+				long k = kv.Key;
 				if (k > timeNow)
 				{
+					minTime = k;
 					break;
 				}
-				foreach (long ll in this.timeId[k])
-				{
-					this.timeOutId.Add(ll);
-				}
-				this.timeId.Remove(k);
+				this.timeOutTime.Add(k);
 			}
 
-			foreach (long k in this.timeOutId)
+			foreach (long k in this.timeOutTime)
 			{
-				Timer timer;
-				if (!this.timers.TryGetValue(k, out timer))
+				foreach (long v in this.timeId[k])
 				{
-					continue;
+					Timer timer;
+					if (!this.timers.TryGetValue(v, out timer))
+					{
+						continue;
+					}
+					this.timers.Remove(v);
+					timer.tcs.SetResult(true);
 				}
-				this.timers.Remove(k);
-				timer.tcs.SetResult(true);
+
+				this.timeId.Remove(k);
 			}
 		}
 
@@ -84,6 +94,10 @@ namespace ETModel
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
+			if (timer.Time < this.minTime)
+			{
+				this.minTime = timer.Time;
+			}
 			cancellationToken.Register(() => { this.Remove(timer.Id); });
 			return tcs.Task;
 		}
@@ -94,6 +108,10 @@ namespace ETModel
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
+			if (timer.Time < this.minTime)
+			{
+				this.minTime = timer.Time;
+			}
 			return tcs.Task;
 		}
 
@@ -103,6 +121,10 @@ namespace ETModel
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
+			if (timer.Time < this.minTime)
+			{
+				this.minTime = timer.Time;
+			}
 			cancellationToken.Register(() => { this.Remove(timer.Id); });
 			return tcs.Task;
 		}
@@ -113,6 +135,10 @@ namespace ETModel
 			Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
 			this.timers[timer.Id] = timer;
 			this.timeId.Add(timer.Time, timer.Id);
+			if (timer.Time < this.minTime)
+			{
+				this.minTime = timer.Time;
+			}
 			return tcs.Task;
 		}
 	}