PowerCollection研究:第2枪小谈RemoveALL算法

前一篇: 第1弹竟就发现不少问题

盯上了BigList的RemoveAll()方法,仔细一看其算法跟List的RemoveAll实现是一致的.
算法很简单,效率很高,但不见得新手都知道.想我以前在这里翻过跟头,拿出来分享一下吧,简单过一遍就是了.
我们知道List在遍历的时候是不能直接删除对象的.于是乎简单明了想到的就是,先遍历一遍发现需要Remove就记录下此Item的index,将其放入一个临时的removeList里.遍历完后,"反向"遍历removeList再一个一个删除之.
今天将这个方法跟List的RemoveAll比较测试了一下,看到结果简直想撞墙.在集合元素数目很大的情况下,有天壤之别.

remove result  3 
当count再大10倍,1,2分钟都没出来结果,主要是removeList太大了,容量要达到500000,系统抗议了.哇塞,中间要产生多少垃圾对象哦.
所幸当count =1000时两者性能差不多,不过增加了垃圾回收负担,还是不划算.

OK,看看RemoveAll算法:

算法很简单,依次遍历一遍把那些不需要remove的item往前放.有个标识low初始值为-1,每次发现不需要Remove的Item就加1,遍历完后所有不需要Remove的Items都已被放在了low之前,因此再统一移除low后面的Items就结束此过程了.整个过程不需要removeList这样的临时容器,不额外产生垃圾对象.

上个简明的图: (remove所有的质数)

 remove

虽然BigList跟List的remove算法一致,但看看效率吧:

remove result

差别是不是很大, ==BigList返回的是所有要被移除的Item的一个集合,List只返回被移除了的个数,不公平.那么让BigList也只返回个数,再比一次结果如何:

remove result  2

还是有不小的差距,原因在于两者使用的底层对象不一样,一个为tree,一个为Array.List凭借着Array对内存操作的先天优势,在Remove操作上依然胜出.


下面是反射出来的List<T>的代码:

public int RemoveAll(Predicate<T> match)
        
{
            
if (match == null)
            
{
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
            }

            
int index = 0;
            
while ((index < this._size) && !match(this._items[index]))
            
{
                index
++;
            }

            
if (index >= this._size)
            
{
                
return 0;
            }

            
int num2 = index + 1;
            
while (num2 < this._size)
            
{
                
while ((num2 < this._size) && match(this._items[num2]))
                
{
                    num2
++;
                }

                
if (num2 < this._size)
                
{
                    
this._items[index++= this._items[num2++];
                }

            }

            Array.Clear(
this._items, index, this._size - index);
            
int num3 = this._size - index;
            
this._size = index;
            
this._version++;
            
return num3;
        }

 

posted @ 2007-06-21 18:45  Anders06  阅读(2541)  评论(8编辑  收藏  举报