在西山居的这篇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. 协议无关组播-密集模式 PIM-DM

    一.组播路由协议 (一) 路由器依靠转发项来转发组播数据包.转发项的生成则是组播路由协议所要完成的任务.组播路由协议有距离矢量组播路由协议(DVMRP).协议无关组播-密集模式(PIM-DM).协议无 ...

  2. T-SQL 类型转换

    use StudentManageDB go --定义变量并查询 declare @sumScore int select @sumScore=(CSharp+SQLServerDB) from Sc ...

  3. MySQL之 Mysqldump导出数据库

    参数大全 参数说明 --all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , -Y 导 ...

  4. CLion使用OpenCV(Ubuntu 18.04)

    项目结构: 设置CMainLists.txt文件中的内容: cmake_minimum_required(VERSION 3.13) project(cv_test) ) find_package(O ...

  5. 1-自己动手编写ArrayList集合

    学习集合的原理,这是一个很简单的代码,没有索引下标越界判断,异常处理等,不够健壮,后面会继续更新完善代码..... 只是入门学习一下 package my; /*** * 自己动手编写一个ArrayL ...

  6. C语言:传值,传地址

    形参:形式参数实参:实际参数 传值: 把实参的值复制给形参, 修改函数内的形参,不会影响实参. 传地址: 指针传值,形参为指向实参地址的指针 当对形参的指向操作时,相当于对实参本身进行的操作 #inc ...

  7. Apached+resin服务搭建

    一.前言 Resin是CAUCHO公司的产品,是一个非常流行的支持servlets 和jsp的引擎,速度非常快.对servlet和JSP提供了良好的支持,性能也比较优良,resin自身采用JAVA语言 ...

  8. 对KVM虚拟机进行cpu pinning配置的方法

    这篇文章主要介绍了对KVM虚拟机进行cpu pinning配置的方法,通过文中的各种virsh命令可进行操作,需要的朋友可以参考下 首先需求了解基本的信息 1 宿主机CPU特性查看 使用virsh n ...

  9. restframwork框架

    一 APIView: class PublishView(APIView): def get(self,request): publish_list=Publish.objects.all() ret ...

  10. centos7安装mysql 8

    1.查看已有mysql(包括mariadb) rpm -pa | grep mariadb yum list installed | grep mariadb rpm -pa | grep mysql ...