现在依旧是在项目里负责一些UI业务的编写。前段时间需要需要给游戏中的 popup提示 做一些简单的重构,正好发现了我一直以来都误解的一个小点,决定记下来。
业务的要求就是做那种会弹出来一会儿再消失的提示,比如道具获取之类的UI。
我的做法就是用一个list去存着当前的提示,并 tick 检查它们是否结束,然后移除已经结束的相关数据。
大概的用法如下。
但其实啊,这个做法在 tick 是非常不好的。同事很快地通过 JetBrainsRider 查看 IL Code ,并告诉我,直接这样传入会每次都 new obj 。有比较大的消耗。
所以在这种需要经常 tick 并且条件比较固定的情况下。我们可以创建好 predicate 然后直接重复使用(可以存在成员变量里,这里演示就直接存在本地变量里了)。
最后附上测试代码和结果 测试 count 为 100000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| public class PredicateTempTest { public struct TempPack { public int tempValue; private static Random s_random = new Random(DateTime.Now.Millisecond); public static TempPack CreateTempPack() { TempPack pack = default; if (s_random == null) { s_random = new Random(DateTime.Now.Millisecond); } pack.tempValue = s_random.Next(0, 10); return pack; } }
private static List<List<TempPack>> s_tempListContainer = new List<List<TempPack>>(10000);
public static void DoTest(int tempCount) { FillTestData(tempCount); DoTestLambda(); DoTestPassMethod(); DoTestPassExistPredicate(); }
private static void FillTestData(int tempCount) { s_tempListContainer.Clear(); s_tempListContainer.Capacity = tempCount; for (int i = 0; i < tempCount; i++) { List<TempPack> tempList = new List<TempPack>(tempCount); s_tempListContainer.Add(tempList); for (int j = 0; j < tempCount; j++) { tempList.Add(TempPack.CreateTempPack()); } } }
private static void DoTestLambda() { Console.WriteLine(""); Console.WriteLine("TestLambda start"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); for (int i = 0, containerSize = s_tempListContainer.Count; i < containerSize; i++) { List<TempPack> tempList = s_tempListContainer[i]; tempList.Find((existPack) => existPack.tempValue % 5 == 0); } stopWatch.Stop(); Console.WriteLine($"TestLambda end, result_{stopWatch.ElapsedMilliseconds}ms"); }
private static void DoTestPassMethod() { Console.WriteLine(""); Console.WriteLine("PassMethod start"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); for (int i = 0, containerSize = s_tempListContainer.Count; i < containerSize; i++) { List<TempPack> tempList = s_tempListContainer[i]; tempList.Find(CheckPack); } stopWatch.Stop(); Console.WriteLine($"PassMethod end, result_{stopWatch.ElapsedMilliseconds}ms"); }
private static void DoTestPassExistPredicate() { Console.WriteLine(""); Console.WriteLine("PassExistPredicate start"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); Predicate<TempPack> predicate = new Predicate<TempPack>(CheckPack); for (int i = 0, containerSize = s_tempListContainer.Count; i < containerSize; i++) { List<TempPack> tempList = s_tempListContainer[i]; tempList.Find(predicate); } stopWatch.Stop(); Console.WriteLine($"PassExistPredicate end, result_{stopWatch.ElapsedMilliseconds}ms"); }
private static bool CheckPack(TempPack pack) { return pack.tempValue % 5 == 0; } }
|