zoukankan      html  css  js  c++  java
  • C# 排序技术研究与对比

    一、 排序场景

    • 一维数组排序
    • 多维数组排序
    • 集合排序,例如Dictionary ,List<T>, 自定义类集合排序等
    • DataTable排序

    二、 排序实现和测试

    1. 一维数组排序

    1.1 一维数组排序特点

        元素之间是一维线性的关系,每个元素只有一个下标,在排序场景下,每个元素的数据类型是一致的。例如:

    clip_image001

    1.2 C# 一维数组排序实现

    A:调用Array.Sort方法实现数组排序,不限制元素数据类型,底层基于对IComparable的接口实现

    clip_image003

    B:使用Linq实现排序

    clip_image004

    1.2 测试结果对比
     

    1000条数据(GUID

    10000数据(GUID

    100000数据(GUID

    Array.Sort

    2ms

    35ms

    420ms

    Linq

    4ms

    74ms

    738ms

    可以看出, Array.Sort排序优于Linq的性能(越底层的结构,排序的性能越好)。

    2. 多维数组排序

    2.1 多维数组排序特点

    数组可以具有多个维度,支持多行多列,各个维度的数据类型可以不同。

    在此文中,交错数组不在研究范围内,主要研究的是不同数据类型的矩阵数组,这样更加贴近我们在实际场景中的数据。例如:

    clip_image005

    2.2 C# 多维数组排序实现

    Step1定义一个对象排序类ObjectComparer,实现IComparer接口,主要负责数组中某个列的排序,

    如果要排序的列是int类型,进行如下比较即可:其他类推。

    clip_image006

    ObjectComparer类结构:

    clip_image007

    Step2定义维度顺序整形数组:tagObjArray,实例化ObjectComparer对象,将要排序的数组作为参数传递给ObjectComparer的构造函数。

    clip_image008

    Step3调用Array.Sort方法排序,参数:维度顺序整形数组:tagObjArray和ObjectComparer对象。

    clip_image009

    3. 集合排序

    3.1.ArrayList 类

    使用大小可按需动态增加的数组。

    clip_image010

    3.2 List 类

    可通过索引访问的对象的强类型列表。提供用于对列表进行搜索、排序和操作的方法,在决定使用 List 还是使用 ArrayList 类(两者具有类似的功能)时, List 类在大多数情况下执行得更好并且是类型安全的。例子中的Sort其实调用的是String.Sort方法。

    clip_image011

    3.3 List和ArrayList性能测试对比
     

    ArrayList

    List

    100000

    498 ms

    538ms

    3.4 Dictionary类/SortedDictionary类

    从数据结构上来说都属于Hashtable,对关键字(键值)进行散列操作,适合键值对的存取,排序可以使用LINQ实现,建议使用SortedDictionary替换。

    Dictionary和HashTable内部实现差不多,但前者无需装箱拆箱操作,效率略高一点

    clip_image012

    clip_image013

    3.5 HashTable类

    Hashtable 主要用于键值快速查找,却没有提供排序的方法,所以它的排序需要借住数组或其它集合来实现。

    clip_image014

    HashTable中的key/value均为object类型,由包含集合元素的存储桶组成。存储桶是 HashTable中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。HashTable的优点就在于其索引的方式,速度非常快。如果以任意类型键值访问其中元素会快于其他集合,特别是当数据量特别大的时候,效率差别尤其大。

    HashTable的应用场合有:对象缓存,树递归算法的替代,和各种需提升效率的场合。

    3.6 Stack类

    Stack,栈,表示对象的简单的后进先出非泛型集合。Push方法入栈,Pop方法出栈。

    3.7 Queue类

    队列,先进先出。enqueue方法入队列,dequeue方法出队列。

    3.8 自定义类集合

    Step1:定义自定义类:Person

    clip_image015

    Step2:构造实体类集合:List<Person> persons

    clip_image016

    Step3:排序方法实现:

    1、直接排序

    clip_image017

    2、Person实现IComparable接口,直接调用Sort方法排序

    clip_image018

    直接调用Sort方法排序

    clip_image019

    3、Linq实现排序

    clip_image020

    测试结果对比:

     

    1.直接排序

    2.实现IComparable接口

    3.Linq

    100000

    75ms

    99ms

    29ms

    4. DataTable排序

    4.1 DataTable特点

    (1)DataTable 对象是按条件区分大小写的。(如果有两个 DataTable对象分别为“mydatatable”和“Mydatatable”,则搜索表的字符串被认为是区分大小写的。如果只有“mydatatable”而不存在“Mydatatable”,则该搜索表的字符串不区分大小写)。

    (2)以编程方式创建 DataTable,须先通过将 DataColumn 对象添加到 DataColumnCollection(通过 Columns 属性访问)中来定义其架构。

    (3)向 DataTable 添加行,须使用 NewRow 方法返回新的 DataRow 对象。(DataTable 可存储的最大行数是 16,777,216)。

    (4)DataTable 也包含可用于确保数据完整性的 Constraint 对象的集合

    (5)DataTable 事件(RowChanged、RowChanging、RowDeleting 和 RowDeleted)可用于确定对表进行更改的时间

    4.2 DataTable排序实现

    Step1: 构造DataTable

    clip_image021

    Step2:DataView排序

    clip_image022

    Step2:DataTable.Select排序

    clip_image023

    4.3 测试结果对比
     

    1.DataView排序

    2.DataTable.Select排序

    100000

    526 ms

    368ms

    对比下自定义类存储100000条相同数据的排序结果:

    测试结果对比:

     

    1.直接排序

    2.实现IComparable接口

    3.Linq

    100000

    75ms

    99ms

    29ms

    三、 排序效率总结

    1、 在数组排序中,建议使用Array.Sort 方式,优于LINQ方式

    2、 在自定义类排序时,推荐使用LINQ方式

    3、 DataTable和自定义类存储同类型数据时,自定义类的排序整体优于DataTable方式。

    4、 DataTable排序时,推荐使用DataTable.Select排序方式。

    5、 Dictionary和HashTable内部实现差不多,但Dictionary无需装箱拆箱操作,效率略高一点。数据量较大时,建议采用HashTable。

    6、 ArrayList集合的排序性能优于List集合。

    7、 Stack和Queue集合用于栈和队列操作。

  • 相关阅读:
    STM8s在利用库配置端口的小问题
    ABAP调试
    READ TABLE 的用法
    人在低谷
    力扣 两数之和
    未来选择
    选择
    室友问题该如何解决呢?
    力扣 两数之和
    谈谈自己
  • 原文地址:https://www.cnblogs.com/vveiliang/p/7883110.html
Copyright © 2011-2022 走看看