美文网首页.Net性能调优
.Net性能调优——泛型和集合

.Net性能调优——泛型和集合

作者: SkylerSkr | 来源:发表于2019-01-07 18:37 被阅读0次

    前言:

    很少有代码能做到不使用集合,如List<T>或Dictionary<K,V>。大型应用可能会同时使用成千上万个集合。对大多数应用来说,根据需要选择或自己编写适当的集合类型,能够带来极大的性能提升。阅读本文你将知道:
    1.为什么要有泛型
    2.为什么说Java是假泛型
    3.CLR泛型的实现
    4.泛型约束
    5.有哪些集合
    6.线程安全集合
    7.集合的内存布局方式对性能的影响

    为什么要有泛型

    我们常常需要创建能用于任何数据类型的类或方法,多态和继承并不总能"药到病除"。在.Net2.0之前,如果方法需要适配任意类型,就只能使用System.Object。这会带来两个问题。
    1.类型安全
    2.装箱
    PS:装箱等基础知识,需自行百度

    为什么说Java是假泛型

    Java编译泛型代码的方式是:移除任何与泛型类型参数有关的信息,取而代之的是Java.lang.Object,这一过程称为类型擦除。
    因为使用Object,编译器可以保持统一,解决了类型安全的问题。但是却解决不了拆装箱

    CLR泛型的实现

    CLR泛型实现:泛型类型(即便是List<>这样的开放类型)是运行的重中之重。每个泛型类型都有一个方法表和EEClass,同时也能生成System.Type实例。当CLR创建封闭类型(List<int>)实例的时候,会根据其开放类型创建方法表和EEClass。
    如果检查实际的方法体,就会发现引用类型的代码不依赖实际类型,只是围绕着引用做文章。而值类型的代码则依赖实际类型,毕竟复制一个整数和一个浮点数是不同的。

    泛型约束

    泛型约束告诉编译器,在使用某个泛型时,只有某些类型能够作为泛型实参。

    public T Create<T>(T element) where T : EntityBase
    {
    }
    public T Create<T>(T element) where T : EntityBase
    {
    }
    public T Create<T>(T element) where T : IFormattable
    {
    }
    public T Create<T>(T element) where T : new()
    {
    }
    public T Create<T>(T element) where T : class
    {
    }
    public T Create<T>(T element) where T : struct
    {
    }
    

    有哪些集合

    List<t>
    LinkedList<T>
    Dictionary<K,V>
    HashSet<T>
    Queue<T>
    Stack<T>
    SortedDictionary<K,V>
    SortedList<K,V>
    SortedSet<T>

    线程安全集合

    ConcurrentStack<T>
    ConcurrentQueue<T>
    ConcurrentBag<T>
    ConcurrentDictionary<K,V>

    集合的内存布局方式对性能的影响

    选择正确的集合所要考虑的不仅仅是性能。对CPU密集型应用来说,数据在内存的布局方式远比其他条件重要,而集合会显著地影响内存布局。
    因内存布局会影响到使用CPU缓存。
    例如:遍历LinkedList<int>和int[],遍历int数组的性能要快上几倍
    在访问数组的元素是,在缓存行开始会有一次缓存未命中,就是会将一个缓存行的数据放入缓存(一个缓存行是64字节)。即16个整数,缓存命中率1:16。但是链表会有前后指针,一个指针4字节,引用类型还有对象头和方法表指针(32位对齐4,64位对齐8),可见缓存命中率该有多低。

    总结:

    请选择合理的集合甚至自定义集合来提升性能吧!

    相关文章

      网友评论

        本文标题:.Net性能调优——泛型和集合

        本文链接:https://www.haomeiwen.com/subject/lscprqtx.html