做一个数据接收监听的测试
两个类
一个有一个静态Arraylist属性
一个是泛型List<Byte[]>现在我接收到的数据都放到该属性和泛型集合中
并且定时清空接收的集合清空的时候属性直接使用 Arraylist = null
list.Clear当重新有数据过来的时候
Arraylist = new Arraylist
list.insert(data)当这个测试运行久了后,请问那个对象占用的资源多点?

解决方案 »

  1.   

    你自己测试吧。当没有明显价值的时候,追性能就成了阻碍。看看List<T>的源代码public void Clear()
    {
        if (this._size > 0)
        {
            Array.Clear(this._items, 0, this._size);
            this._size = 0;
        }
        this._version++;
    }
    它没有去new一个新的对象,但是调用了Array.Clear。
      

  2.   

    参考List<T> 模板是可以在编译器进行优化的如果用List<byte>,编译器可以提前确定list存储的是值类型,用专用的结构来优化ArrayList是没有这个能力的如果是存储引用类型,两者没有区别
      

  3.   

    其实有一点我没有搞懂,你为什用
       Arraylist = null
       list.Clear
    这样两条代码做对比,而不用
       Arraylist = null
       list=null
    呢?
      

  4.   

    这个得考虑你的环境和应用场合吧,最好还是自己用Stopwatch来监控一下,把数据写入log文件来进行比对。
      

  5.   

    看了半天,都没说到点子上去,老夫来解答。
    1 C#既然追求单根,为啥还要搞泛型呢。很多原因。和这个帖子有关的两个原因:强类型和性能。
    2 显然List<Byte[]> 和 Arraylist是不一样的。具体到就是就是
        Arraylist 装进去的非引用类型数据,CLR会进行装箱操作。例如:int i; Arraylist al = new Arraylist();
        al.Add(i);。实际上CLR会给i做个Box,然后把引用类型放到list中。出来的时候呢,就做拆箱操作。
        而是用泛型则不同,不会有这方面的损失。
        就像买东西,一个直接给钞票。一个刷卡。
        做个测试就知道了。大数据时,性能差一个数量级,可不是闹着玩的。
    3 强类型。显然泛型的定义会避免很多错误。如果你定义了一个Arraylist ,那么别人可能要看你代码才知道里到底能装什么玩意。但泛型定义后,那么装什么一目了然了。楼主可以关注另一个类:BaseCollection。这个东西是为了让你用Arraylist也能强类型的。但性能上,和Arraylist一样。
    4 注意装箱陷阱。这个很多人都遇到过吧。举个例子;
            struct myStruct 
            {
                public myStruct(int _x)
                {
                    x = _x;
                }
                public int x;
            }
                ArrayList al = new ArrayList();
                al.Add(new myStruct(0));
            我现在想把数组里的al[0]里的myStruct 的x字段改成1,怎么办呢。其实是很难办。
            这样写:((myStruct)al[0]).x = 2;以前工具不会报错,但对不起,你掉进装箱陷阱了。现在
            VS2008直接就是编译不过。
            这样写:            myStruct my2 = ((myStruct)al[0]); my2.x = 2;
             对不起,其实根本没改。at[0]中myStruct的x字段还是0。
            所以泛型还有个常用的地方,对待值类型的,一般用泛型。
      

  6.   

    6楼分析的很详细,但是其实我是想做一个这样的测试,做一个客户端的socket监听,然后new一个list还是Arraylist来接收数据好?因为该客户端是24 * 365 开的,数据也会不停的发送过来,所以当集合里面的byte[]数组到一定容量时我会清空。然后继续监听接收数据,我这里想问的是,当接收数据的时候是定义一个list不停的接收到容量一定的时候clear好?还是到一定容量的时候设置null,然后当有新的数据的时候又new一个好。就是一个类常驻内存好,还是定时的null的释放又新建好。
      

  7.   

    1  你的需求很具有代表性。实际上解决办法很多,主要看你对内存控制欲望到底有多大。
    2  C# 中 Clear和 = null。没有本质上的区别。因为不存在显式销毁内存的事,事实上你没法显式销毁内存,
         就算你 = null。也就是告诉GC,这个内存我不用了,你可以回收。至于你用Clear好还是 null好,这个
          要看GC实现的细节。恐怕很难说,也不会差别很大。
          这点和C++很不一样。
    3 但是常驻内存是另一回事。这有几个好处:
       (1)避免GC回收内存,无疑性能上好很多。在大数据情况下,性能提升是非常明显的。这个无容置疑。
       (2)避免内存碎片产生。这个了解下内存分配的机制你就会明白。特别是你每次都需要比较大的内存时,
                 没完没了地删了再建,即会浪费空间,又非常影响性能。这个在一些内存受限的系统中很重要。比如
                一些手机中,内存本来就很少。
    4 如果你要频繁得接收大数据,一个非常好的接收缓冲区设计是很重要的。在C++中一般使用静态的循环数组
       来实现。一个静态的循环数组,首先,空间事先分配好,不需要new,节省时间。其次,内存分配空间连 续,读取效率高。最重要的,不需要delete。测试下就知道,delete耗费的CPU时间比new高几个数量级。
     5 C#中,由于本身的问题,想做到C++那么高效是很难的。不过一样可以预先分配一个很大的byte []数组,
        做一个循环队列。如果你用arraylist。那么上面的当没说,你怎么做效率都不会高,
      

  8.   

    路过,学习啦。6楼的解释很不错。让我对List<T> 和 Arraylist有了进一步的认识