在西山居的这篇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 = ;
adx = new double[ix];
for(int i=; 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[]; }
static void testStructMem()
{
ST ot = new ST();
ST ot2 = new ST(); var st = Stopwatch.StartNew();
var t1 = st.ElapsedMilliseconds;
for(int i=; i<; ++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=; i<; ++i)
{
var eq = oc.Equals(oc2);
}
var t12 = st2.ElapsedMilliseconds;
Console.WriteLine(t12 - t11);//5ms,与类的复杂度无关,这说明比较的是引用(地址)
}
#endregion

关于STRUCT优化的一个点的更多相关文章

  1. VS编译器优化诱发一个的Bug

    VS编译器优化诱发一个的Bug Bug的背景 我正在把某个C++下的驱动程序移植到C下,前几天发生了一个比较诡异的问题. 驱动程序有一个bug,但是这个bug只能 Win32 Release 版本下的 ...

  2. 一步步做程序优化-讲一个用于OpenACC优化的程序(转载)

    一步步做程序优化[1]讲一个用于OpenACC优化的程序 分析下A,B,C为三个矩阵,A为m*n维,B为n*k维,C为m*k维,用A和B来计算C,计算方法是:C = alpha*A*B + beta* ...

  3. 重度使用示波器进行优化分析——一个DSDA项目回顾

    这是若干年前一个项目,最近有时间整理一下.回忆起来,印象最深刻的就是重度使用示波器辅助分析,进行优化. 项目背景是在原有项目3G+项目基础上,增加一颗2G+ Modem,使支持DSDA功能. 在介绍D ...

  4. 重度使用示波器进行优化分析——一个DSDA项目回顾

    这是若干年前一个项目,最近有时间整理一下.回忆起来,印象最深刻的就是重度使用示波器辅助分析,进行优化. 项目背景是在原有项目3G+项目基础上,增加一颗2G+ Modem,使支持DSDA功能. 在介绍D ...

  5. struct 模块 把一个类型,如数字,转成固定长度的bytes

    该模块可以把一个类型,如数字,转成固定长度的bytes import struct headers=struct.pack('i',132333) print(headers,len(headers) ...

  6. 整型转字符串(convert int to char)优化实践——一个意外的BUG

    convert_int_to_char函数在使用时出现过一个BUG. 当使用值是13200020099时,返回的字符串是"13200020111",结果是错误的. 在gcc编译器里 ...

  7. 简单聊聊TiDB中sql优化的一个规则---左连接消除(Left Out Join Elimination)

    我们看看 TiDB 一段代码的实现 --- 左外连接(Left Out Join)的消除; select 的优化一般是这样的过程: 在逻辑执行计划的优化阶段, 会有很多关系代数的规则, 需要将逻辑执行 ...

  8. 转PostgreSQL 用游标优化的一个例子

    一位PG社区的朋友提到的一个应用场景,目前遇到性能问题. 数据结构大概是这样的,包含一个主键,一个数组,一个时间,其他字段. 请求分析: 有检索需求,比较频繁.查找数组中包含某些元素的记录,并按时间排 ...

  9. 关于SQL语句优化的一个问题

    今天写了一个很简单的存储过程,结果一执行,40多秒,后来调整了一句话写法,瞬间出来,其实差别不大,如下: select item_no=vpc.ITEM_ID ,BL_QTY=sum(vpc.QTY_ ...

随机推荐

  1. [UE4]Transform镜面翻转

  2. 使用IDEA进行Lua代码调试、自动提示、代码跳转、智能重命名

    试了几个Lua IDE后,Lua Studio.Lua Glider.VS+babelua插件.Sublime都不是特别满意.直到发现了国人自创的另一个神奇工具:基于IDEA的EmmyLua插件.该插 ...

  3. PhysX Clothing for UE4

    转自:http://www.52vr.com/article-737-1.html Hello! 之前看到论坛里有人发了个关于UE4布料的小知识,于是跟帖说抽空写个布料的工作流程供大家参考,那么,今天 ...

  4. 在Docker中安装配置Oracle11g并实现数据持久化

    1.拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g 镜像详情:https://dev.aliyun.com/ ...

  5. 基于pyQt5开发的股价显示器(原创)

    #/usr/bin/env python # -*- coding: utf-8 -*- ''' @author="livermorium116" 为了绕开公司内网而开发的 股票实 ...

  6. Spark2.X分布式弹性数据集

    跑一下这个结果 参考代码 package com.spark.test import org.apache.spark.sql.SparkSession import org.apache.spark ...

  7. SDOI2018IIIDX

    /* 题目转换为 n个节点的一片森林,n个权值,要给每个节点分配一个权值,保证子节点的权值不小于父节点的权值,并且1~n的权值的字典序最大. 考场上的贪心很显然 建立出 树来 将所有数值从大到小排序 ...

  8. ping -c 3 localhost

    linux指令,ping -c count ip,向指定IP发送指定数量的ping包

  9. crawlspider 多分页处理

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  10. Linux实用命令整理

    说明 点击标题可进入详细讲解的章节 0. 基本命令 linux 基本命令整理 1. 压缩 解压 tar -zcvf a.tar.gz a #把a压缩成a.tar.gz tar -zxvf a.tar. ...