内容简介:cocos转unity笔记(二)C#的ArrayList和List性能对比
接上篇,发现一个神奇的现象,List<object>的存储速度比List<T>的速度要快
性能测试准备
既然要做性能测试,那我们肯定需要一个 工具 来统计代码块运行时间。C#里有现成的时间函数供我们使用,一般都是这么写:
var time1 = System.DateTime.Now; // 会花掉很多时间的代码 var time2 = System.DateTime.Now; var diff = time2.Subtract(time1); Console.WriteLine("Time Cost: {0}ms", diff.TotalMilliseconds);
有点儿麻烦,那我封装一下好了,成这样:
class TimeCount { private DateTimem_startTime; private bool m_started; public TimeCount() { m_started = false; m_startTime = System.DateTime.Now; } public void start() { m_started = true; m_startTime = System.DateTime.Now; } public double stop() { if (!m_started) { return 0; } TimeSpandiff = System.DateTime.Now.Subtract(m_startTime); double ret = diff.TotalMilliseconds; return ret; } };
直接调用Start和End就行
ArrayList和List<object>
现在网上所有的说法都不赞同使用ArrayList这个非泛型容器。理由是:
- 效率低下,涉及基本类型的保存时会产生装箱拆箱的操作,损失很大一部分性能
- 就算有时候我们有需要Listobject这样的容器,但是还是尽量写成Listobj,写成ArrayList会和其他List显得不整齐
是这样没错,尤其是第二条,所以我们直接抛弃掉ArrayList的写法实际上,ArrayList和Listobj的效率是一样的,用如下代码测试:
System.Collections.ArrayListl0 = new System.Collections.ArrayList(); tc.start(); for (var i = 0; i < 1000000; ++i) { ClassDataitem = new ClassData(); item.intValue = i; l0.Add(item); } Console.WriteLine("Time Cost: {0}ms -- create l0", tc.stop()); List<object> l1 = new List<object>(); tc.start(); for (var i = 0; i < 1000000; ++i) { ClassDataitem = new ClassData(); item.intValue = i; l1.Add(item); } Console.WriteLine("Time Cost: {0}ms -- create l1", tc.stop());
输出结果如下:
于是我们就不再考虑ArrayList了
List<object>和List<T>
这里的T是我们自定义的一个结构体或类
至于这里到底是结构体还是类,测试结果相差很远。
结构体
先看结构体的情况:
struct StructData { public int intValue; };
接下来是测试代码:
List<int> l3 = new List<int>(); tc.start(); for (var i = 0; i < 1000000; ++i) { l3.Add(i); } Console.WriteLine("Time Cost: {0}ms -- create l3", tc.stop()); List<object> l4 = new List<object>(); tc.start(); for (var i = 0; i < 1000000; ++i) { l4.Add(i); } Console.WriteLine("Time Cost: {0}ms -- create l4", tc.stop());
多执行几次,运行结果如下:

可以看到,当我们打算用List<T>存储结构体时,最好不要用List<object>,因为在存储的时候必须进行装箱的操作,也就是把存储于栈的结构体保存到堆中,这会极大地损耗性能
类
如果T不是结构体而是一个我们手动new出来的对象,那么理论上就不存在装箱和拆箱的操作了,然后再试试
// 类的声明 class ClassData { public int intValue; }; // 测试代码 List<object> l1 = new List<object>(); tc.start(); for (var i = 0; i < 1000000; ++i) { ClassDataitem = new ClassData(); item.intValue = i; l1.Add(item); } Console.WriteLine("Time Cost: {0}ms -- create l1", tc.stop()); List<ClassData> l2 = new List<ClassData>(); tc.start(); for (var i = 0; i < 1000000; ++i) { ClassDataitem = new ClassData(); item.intValue = i; l2.Add(item); } Console.WriteLine("Time Cost: {0}ms -- create l2", tc.stop());
同样多执行几次,运行结果如下:

咦,List<MyClass>的速度居然还不如List<object>
我也不太清楚为啥会这样,估计是List<MyClass>存的时候需要进行类型检查,这一步消耗了一定的时间吧
其实这一篇也没啥实际意义,在实际的应用中还是尽量用List<MyClass>吧,既不用考虑装箱导致的性能损耗,又能保证类型安全,损失的部分性能也是可以接受的,除非某些对应能特别敏感的需求。
PS. 新的发现,在List<object>和List<T>的对比中,使用macOS下的monoDevelop产生的结果会比较整齐,在Windows10下使用VS2015产生的结果会比较不整齐,统计出来的时间起伏较大
下一篇开始正儿八经做游戏啦
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Kubernetes 存储性能对比
- 快排和堆排性能对比
- 性能压测工具选型对比
- 性能对比:ReentrantLock vs Synchronized
- Mobx 与 Redux 的性能对比
- Protobuf的使用及性能对比测试
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。