zoukankan      html  css  js  c++  java
  • Unity中的拆/装箱操作引发的GC问题解决方案

    Unity C#开发中,常常用到Enum或Struct等类型作为Dictionary的key,或List的元素,即:

    List<EnumType>,Dictionary<EnumType, ValueType>,List<StructType>,Dictionary<StructType, ValueType>。

    在List的Contains()、Dictionary的ContainsKey()或[]操作时,会调用Equals()和GetHasCode(),从而对Enum或Struct类型进行装箱操作,产生GC问题。

    解决方案:

    1、Struct,override GetHasCode()并实现IEquatable<T>即可。例如:

    /// <summary>
            /// sizeof(KeyStruct) = 12B
            /// 测试Dictionary的Contains()和[]
            /// 1.不override GetHashCode()和实现IEquatable<T>
            ///     Contains():84B
            ///     []:84B
            /// 2.只实现实现IEquatable<T>
            ///     Contains():28B
            ///     []:28B
            ///     []:84B
            /// 3.只override GetHashCode()
            ///     Contains():56B
            ///     []:56B
            /// 4.override GetHashCode()和实现IEquatable<T>
            ///     Contains():0
            ///     []:0
            /// </summary>
            struct KeyStruct : IEquatable<KeyStruct>
            {
                public int a;
                public int b;
                public int c;
    
                public KeyStruct(int a, int b, int c)
                {
                    this.a = a;
                    this.b = b;
                    this.c = c;
                }
    
                public override int GetHashCode()
                {
                    return this.a * 100 + this.b * 10 + this.c;
                }
    
                public bool Equals(KeyStruct obj)
                {
                    return this.a == obj.a && this.b == obj.b && this.c == obj.c;
                }
            }

    2、Enum类型由于不能override和implement接口,需要使用其他方法。

    当作为Dictionary key使用时,可以为Enum定义一个专用比较器,如下:

            enum KeyEnum
            {
                K1,
                K2,
                K3,
                K4,
            }
    
            struct KeyEnumComparer : IEqualityComparer<KeyEnum>
            {
                public bool Equals(KeyEnum x, KeyEnum y)
                {
                    return x == y;
                }
    
                public int GetHashCode(KeyEnum obj)
                {
                    // you need to do some thinking here,
                    return (int)obj;
                }
            }
    
            Dictionary<KeyEnum, KeyEnum> enumDict2 = new Dictionary<KeyEnum, KeyEnum>(new KeyEnumComparer())
            {
                {KeyEnum.K1,KeyEnum.K1},
                {KeyEnum.K2,KeyEnum.K1},
                {KeyEnum.K3,KeyEnum.K1},
                {KeyEnum.K4,KeyEnum.K1}
            };

    List中使用Enum,由于无法在构造函数中传入自定义比较器,推荐使用List.Exists(e => e == KeyEnum.K1)代替List.Contains(KeyEnum.K1),以避免Equals()调用。

    作者:dongzee
    出处:http://www.cnblogs.com/dongzee
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接
    如有问题,可以通过  dongzee1984#gmail.com  联系我,非常感谢。

  • 相关阅读:
    数据库连接池系列之——c3p0
    spring配置
    flume ng系列之——flume安装
    flume ng之组件介绍
    flume ng之TailSource
    Flume-NG + HDFS + HIVE日志收集分析
    flume+hadoop
    Flume+kafka+storm+hdfs
    IOS中坐标转换
    tabBarItem是模型,只有控件才有textColor属性
  • 原文地址:https://www.cnblogs.com/dongzee/p/8622952.html
Copyright © 2011-2022 走看看