我看目前很火的IT小说。。。原创文学网 - 纯净的绿色文学家园 !

我看目前很火的IT小说。。。

我看目前很火的IT小说。。。(全文在线阅读> 

瑶池中,玉帝与王母仍在酣饮,玉帝道:“你这计策果真高明,先前连我都瞒过了。”

儿童为什么自伤?

小小年纪能有这么一番成绩可不容易,也不知道是谁下手这么狠,要把丁宁往死里整。
花叶道:“实不相瞒,这艘游轮乃是我们落云宫的产业,见到修真界同道,自然是要见上一见的。”

“我这样算不算是回到了神奇宝贝世界那样丢出一个精灵球放出了一个神奇宝贝呢。”刘皓心里笑着想。

深入探讨List<>中的一个姿势。


距离上一篇博文,差不多两年了。终于憋出来了一篇。[手动滑稽]

List<>是c#中很常见的一种集合形式,近期在阅读c#源码时,发现了一个很有意思的定义:

    [DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
    [DebuggerDisplay("Count = {Count}")]
    [Serializable]
    public class List<T> : IList<T>, System.Collections.IList, IReadOnlyList<T>
    {
        private const int _defaultCapacity = 4;
 
        private T[] _items;
        [ContractPublicPropertyName("Count")]
        private int _size;
        private int _version;
        [NonSerialized]
        private Object _syncRoot;
        
        static readonly T[]  _emptyArray = new T[0];        
            
        // Constructs a List. The list is initially empty and has a capacity
        // of zero. Upon adding the first element to the list the capacity is
        // increased to 16, and then increased in multiples of two as required.
        public List() {
            _items = _emptyArray;
        }
    }
    ...
    ...
    ...
    private void EnsureCapacity(int min) {
        if (_items.Length < min) {
            int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
            if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
            if (newCapacity < min) newCapacity = min;
            Capacity = newCapacity;
        }
    }

咦,_defaultCapacity = 4, _items.Length * 2。抱着怀疑的态度,有了以下这一篇文章。

defaultCapacity=4?

带着怀疑的态度,我们新建一个Console程序,Debug一下。

var list = new List<int>();
Console.WriteLine(list.Capacity);

运行结果:
图片:

...怎么是0呢?一定是我打开的姿势不对,再看一下源码。发现:

static readonly T[]  _emptyArray = new T[0];
...
...
public List() {
     _items = _emptyArray;
}

哦,这就对了,初始化时候当然是0。那这个_defaultCapacity有何用?继续看源码。

 if (_items.Length < min) {
    int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;

发现这个三元表达式,为什么要这样做呢?翻了一下google,发现了这样一段文字:

List实例化一个List对象时,Framework只是在内存中申请了一块内存存放List对象本身,系统此时并不知道List会有多少个item元素及元素本身大小。当List添加了第一个item时,List会申请能存储4个item元素的存储空间,此时Capacity是4,当我们添加第五个item时,此时的Capacity就会变成8。也就是当List发现元素的总数大于Capacity数量时,会主动申请且重新分配内存,每次申请的内存数量是之前item数量的两倍。然后将之前所有的item元素复制到新内存。

上面的测试,Capacity=0已经证明了上述这段话的

List实例化一个List对象时,Framework只是在内存中申请了一块内存存放List对象本身,系统此时并不知道List会有多少个item元素及元素本身大小。

接下来我们证明

当List添加了第一个item时,List会申请能存储4个item元素的存储空间,此时Capacity是4
图片:

RT,接下来,我们证明

我们添加第五个item时,此时的Capacity就会变成8。
图片:

RT,的确是这样。
那是否我们得出一个结论,因为不定长的List在Add的时候,频繁的重新申请、分配内存、复制到新内存,效率是否还可以再提升一下呢?
我们先试一下

for (int i = 0; i < count; i++)
{
    var listA = new List<int>(10);
    listA.Add(i);
}
循环次数 定长长度 运行时间
100 0 144
100 5 23
100 6 49
100 7 45
100 8 73
100 9 21
100 10 22

运行结果:注定长为0表示未设置List长度

循环次数 定长长度 运行时间
10000 0 3741
10000 5 3934
10000 6 4258
10000 7 4013
10000 8 4830
10000 9 4159
10000 10 2370

好吃鲸...为啥9和10差距这么多。。。
我们加大循环次数。结果:

循环次数 定长长度 运行时间
1000000 0 317590
1000000 5 263378
1000000 6 150444
1000000 7 157317
1000000 8 139041
1000000 9 124714
1000000 10 120547

随着循环次数、定长的增加,可以看出,频繁的重新申请、分配内存、复制到新内存,是很耗费时间和性能的。
在以后的工作中,如果有频繁的List.Add,特别是循环Add,不妨考虑一下给List设置一个定长。

当前文章:http://peakfog.com/41392.html

发布时间:2019-03-27 02:44:11

如何应该孩子的负面情绪 你相信这超凡脱俗的爱情吗? 罗李华谈:属兔的人2016年运程 文创监理 - 黄胤然首倡文创理念 冬季放生龟鳖类要考虑的注意事项 向死而生:从《道士下山》到天津爆炸,来谈谈生死 北京高考新政的N个变化 网购化妆品怎么辨别真伪

青春期——改变人生的最后机会 老子之励志 护肤必备手册之(二)周期护理 一个人是怎样一步步变狭隘的 老公出轨之后我对他的恨意该如何消除呢? 不要用战术上的忙碌掩盖战略上的懒惰 总得有点真东西 八个奇怪心理不解之谜 建国以来最大规模的阅兵-2015阅兵 阴魂不散的前女友 吃点温暖 中国女性在慌什么—Joy陈愉谈事业、爱情、婚姻 董卿为什么没有被狐狸狗催眠? 情话和性话,男女怎么说才受用? 宝宝半夜耳痛为哪般 魏则西事件让百度在失去了什么? 玩你的招聘企业,你看出来了吗? 揭露人性丑恶的五大心理实验 护肤必备手册之(二)周期护理

编辑:乙卓公

 
分享到: 更多
作品集
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
推荐文章