zoukankan      html  css  js  c++  java
  • 关于STRUCT优化的一个点

    在西山居的这篇U3D cheatsheet中,提到: c12. 确保 struct 实现了 Equals() 和 GetHashCode()

    这怎么理解?

    首先,看下system.object.equals和 ReferenceEquals的实现:

    public static bool ReferenceEquals (object objA, object objB)
    {
    return objA == objB;//这就说明 了==比较的是引用
    }

    public virtual bool Equals (object obj)
    {
    return object.InternalEquals (this, obj);
    }

    如果是引用类型,比较时只需比较两个引用的值(地址,指针)是否相等即可。

    对于值类型的结构体,将发生由值到object的装箱操作,生成两个堆对象,地址分别存放在objA,objB中,objA==objB 必定不成立,因为没有任何两个结构体的内存地址会相同,那么它就进行InteranlEquals 的比较,这个比较是在DLL中写的,看不到源码,

    通过对结构体进行1000000次equals测试发现,结构体中类型越多,越复杂,则equals越慢,而引用类型则不会这样。

    测试及结论如下:

        class Program
        {
            #region 结构体内存分配测试
            struct ST
            {
                public float fx;
                //public string name;
                int ix;
                double[] adx;
    
                public ST(float afx, string aName)
                {
                    fx = afx;
                    //name = "10"; // "hello,world, 你好吗,!@#($)%%@$";
                    ix = 10000000;
                    adx = new double[ix];
                    for(int i=0; i< ix; ++i)
                    {
                        adx[i] = i * i;
                    }
                }
            }
            class CX
            {
                public float fx;
                string name = "hello,world, 你好吗,!@#($)%%@$";
                string name2 = "11111122334dfasdfd";
                string name3 = "xhello,world, dssccccc$aa$";
                double[] adx = new double[100];
    
            }
            static void testStructMem()
            {
                ST ot = new ST();
                ST ot2 = new ST();
    
                var st = Stopwatch.StartNew();
                var t1 = st.ElapsedMilliseconds;
                for(int i=0; i<1000000; ++i)
                {
                    var eq = ot.Equals(ot2);
                }
                var t2 = st.ElapsedMilliseconds;
    
                //616ms,随着类的复杂度而上升,字符串类型,数组类型最消耗
                //且,一个元素的数组与10000个元素的数组几乎没有区别,这说明消耗在类型而不在数据长度
                //由此,可以判定,在进行结构体类型的比较时,是遍历结构内的所有成员,对每个成员先判断其类型,再进行哈希值比较
                //为什么要先判类型?只比较字节码不行吗?显然不行,对相同的字节码作不同类型的解释得到的是不一样的结果
                Console.WriteLine(t2 - t1); //616ms
    
                var oc = new CX();
                var oc2 = new CX();
                var st2 = Stopwatch.StartNew();
                st2.Start();
                var t11 = st2.ElapsedMilliseconds;
                for(int i=0; i<1000000; ++i)
                {
                    var eq = oc.Equals(oc2);
                }
                var t12 = st2.ElapsedMilliseconds;
                Console.WriteLine(t12 - t11);//5ms,与类的复杂度无关,这说明比较的是引用(地址)
            }
            #endregion
  • 相关阅读:
    中国科学院2021年硕转博考试分析试题参考解答
    蒲和平大学生数学竞赛教程答案5.1.3
    清华大学2021年数学推荐免试试题参考解答
    蒲和平大学生数学竞赛教程答案4.1.1
    兰州大学历年数学分析高等代数考研试题答案
    复旦大学2021年数学英才实验班选拔考试试题参考解答pdf
    北京大学2021年基础学科招生考试数学试题
    南开大学2021年数学伯苓班/复旦大学2021年数学英才实验班选拔考试试题
    实变函数与泛函分析第05次课:至1.5.2(请点阅读全文进课堂)
    中国科学技术大学2021年新生入学考试试题
  • 原文地址:https://www.cnblogs.com/timeObjserver/p/9597788.html
Copyright © 2011-2022 走看看