zoukankan      html  css  js  c++  java
  • LinkedList 和 List 在三种简单算法中效率比较

    LinkedList List 在三种简单算法中效率比较

    .Net 框架提供了两种List类型,一种是基于链表的LinkedList, 一种是基于数组的List。那么在实际应用中到底采用哪种List,如何取舍呢?本文对两种类型在队列,堆栈和简单插入三种简单算法中的效率进行了一个比较。

    首先先让我们来看一下List的初始容量CapacityList的性能是否有影响。

    测试方法:分别设置初始容量为0642551024. List插入的最大长度为1000,循环1000次,得到如下结果,单位为ms,下同。

    算法/初始容量

    0

    64

    255

    1024

    队列

    35837

    35753

    37171

    35711

    堆栈

    302

    279

    298

    289

    简单插入

    100

    105

    100

    100

     

    从上面数据中我们可以看出List的初始容量对效率没有明显影响。

    队列算法比较

    测试方法:对LinkedListList采用先进先出的队列算法,分别设置队列最大长度为103050100100010000,并循环1000次,得到如下结果。

    List类型/队列最大长度

    10

    30

    50

    100

    1000

    10000

    LinkedList

    0.7659

    0.8768

    1.1041

    2.0401

    61

    691

    List

    0.3326

    1.1677

    1.9985

    12

    443

    37516

     

    从测试结果中我们可以看出LinkedList 随着最大队列长度的增加,所用时间基本成线性增长。而List则成指数增长。我分析主要原因应该是每次删除List的数组头时,List都要做一次整个数数组的拷贝,而链表类型则不存在这个问题。有趣的是当队列长度小于30时,List的效率要比LinkedList要高,这主要是因为链表在增删元素时需要额外创建链表指针,而数组不需要这个操作。在队列长度较小时,这种开销就会显得很明显。

    堆栈算法比较

    测试方法:对LinkedListList采用先进后出的堆栈算法,分别设置队列最大长度为103050100100010000,并循环1000次,得到如下结果。

    List类型/堆栈最大长度

    10

    30

    50

    100

    1000

    10000

    LinkedList

    0.8515

    0.9295

    1.1123

    2.1874

    58

    714

    List

    0.1109

    0.3104

    0.5118

    1.2256

    29

    284

    从测试结果看两种类型都是线性增长,但List的性能更高一些。我分析这主要是因为List类型在增长到最大值后在从尾部删除元素,其并不重新分配内存,除非你强行让它压缩。所以List从尾部删除只是将Count改变了一下,因此效率很高。而链表类型的效率和队列方式基本相当,这也是在预料之中的,其效率比List低的原因主要还是在增删时创建和删除节点的额外开销。

    简单插入算法比较

    测试方法:对LinkedListList采用向后追加若干元素的算法,分别设置插入最大长度为103050100100010000,并循环1000次,得到如下结果。

    List类型/插入最大长度

    10

    30

    50

    100

    1000

    10000

    LinkedList

    0.6778

    0.765

    0.938

    1.7783

    40

    535

    List

    0.0864

    0.1661

    0.2509

    0.4312

    10

    109

     

    其测试结果和堆栈算法基本类似,且List的效率更高,这里不再重复论述。

     

    总结

    如果采用队列算法建议采用LinkedList类型,除非队列长度小于30.

    如果采用堆栈或简单插入算法,建议采用List类型。但有一点需要说明,如果应用对内存占用有限制,建议采用LinkedList类型。

     

    测试代码

     

        class Program
        
    {
            
    const int TEST_TIMES = 1000;

            
    static private void TestQueue(int count)
            
    {
                TestQueue(count, 
    0);
            }


            
    static private void TestQueue(int count, int capacity)
            
    {
                Console.WriteLine(
    "Count:" + count.ToString());

                LinkedList
    <int> linkList = new LinkedList<int>();
                List
    <int> list = new List<int>(capacity);


                Stopwatch watch 
    = new Stopwatch();
                watch.Start();

                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        linkList.AddLast(j);
                    }


                    
    for (int j = 0; j < count; j++)
                    
    {
                        
    int test = linkList.First.Value;

                        linkList.RemoveFirst();
                    }

                }


                watch.Stop();

                String duration;
                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "LinkedList:" + duration);

                watch.Reset();
                watch.Start();
                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        list.Add(j);
                    }


                    
    for (int j = 0; j < count; j++)
                    
    {
                        
    int test = list[0];

                        list.RemoveAt(
    0);
                    }

                }


                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "List:" + duration);
            }


            
    static private void TestStack(int count)
            
    {
                TestStack(count, 
    0);
            }


            
    static private void TestStack(int count, int capacity)
            
    {
                Console.WriteLine(
    "Count:" + count.ToString());

                LinkedList
    <int> linkList = new LinkedList<int>();
                List
    <int> list = new List<int>(capacity);


                Stopwatch watch 
    = new Stopwatch();
                watch.Start();

                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        linkList.AddLast(j);
                    }


                    
    for (int j = 0; j < count; j++)
                    
    {
                        
    int test = linkList.Last.Value;

                        linkList.RemoveLast();
                    }

                }


                watch.Stop();

                String duration;
                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "LinkedList:" + duration);

                watch.Reset();
                watch.Start();
                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        list.Add(j);
                    }


                    
    for (int j = 0; j < count; j++)
                    
    {
                        
    int test = list[list.Count-1];

                        list.RemoveAt(list.Count 
    - 1);
                    }

                }


                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "List:" + duration);
            }


            
    static private void TestInsert(int count)
            
    {
                TestInsert(count, 
    0);
            }


            
    static private void TestInsert(int count, int capacity)
            
    {
                Console.WriteLine(
    "Count:" + count.ToString());

                LinkedList
    <int> linkList = new LinkedList<int>();
                List
    <int> list = new List<int>(capacity);


                Stopwatch watch 
    = new Stopwatch();
                watch.Start();

                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        linkList.AddLast(j);
                    }


                    linkList.Clear();
                }


                watch.Stop();

                String duration;
                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "LinkedList:" + duration);

                watch.Reset();
                watch.Start();
                
    for (int i = 0; i < TEST_TIMES; i++)
                
    {
                    
    for (int j = 0; j < count; j++)
                    
    {
                        list.Add(j);
                    }


                    list.Clear();
                }


                
    if (watch.ElapsedMilliseconds < 10)
                
    {
                    duration 
    = (((double)watch.ElapsedTicks) / 10000).ToString() + "ms";
                }

                
    else
                
    {
                    duration 
    = watch.ElapsedMilliseconds.ToString() + "ms";
                }


                Console.WriteLine(
    "List:" + duration);
            }



            
    static void Main(string[] args)
            
    {
                
    //capacity
                TestQueue(100000);
                TestQueue(
    1000064);
                TestQueue(
    10000255);
                TestQueue(
    100001024);

                TestStack(
    100000);
                TestStack(
    1000064);
                TestStack(
    10000255);
                TestStack(
    100001024);

                TestInsert(
    100000);
                TestInsert(
    1000064);
                TestInsert(
    10000255);
                TestInsert(
    100001024);

                
    //compare LinkedList and List
                TestQueue(10);
                TestQueue(
    30);
                TestQueue(
    50);
                TestQueue(
    100);
                TestQueue(
    1000);
                TestQueue(
    10000);

                TestStack(
    10);
                TestStack(
    30);
                TestStack(
    50);
                TestStack(
    100);
                TestStack(
    1000);
                TestStack(
    10000);

                TestInsert(
    10);
                TestInsert(
    30);
                TestInsert(
    50);
                TestInsert(
    100);
                TestInsert(
    1000);
                TestInsert(
    10000);
                

                


            }

        }

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    Oracle常见授权与回收权限——grant和revoke
    数据库之笛卡尔积
    hdu 2032 一维数组实现杨辉三角
    poj3071之概率DP
    冒泡排序及两种优化方式
    Non-ASCII character &#39;xe8&#39; in file xxx.py on line 8, but no encoding declared
    编写shell脚本获取本机的网络地址。&#160; 比方:本机的ip地址是:192.168.100.2/255.255.255.0,那么它的网络地址是&#160;192.168.100.1/255.255.255.
    移动站点性能优化
    Math类概述及其成员方法
    java中StringBuilder、StringBuffer、String类之间的关系
  • 原文地址:https://www.cnblogs.com/eaglet/p/1188546.html
Copyright © 2011-2022 走看看