在西山居的这篇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. mikrotik ros CVE-2019–3924 DUDE AGENT VULNERABILITY

    原文: https://blog.mikrotik.com/security/cve-20193924-dude-agent-vulnerability.html The issue is fixed ...

  2. PLSQL导出对象的表结构和表数据

    https://jingyan.baidu.com/article/fcb5aff78e6a48edab4a7146.html

  3. 4G模块*99#拨号上网

    操作系统:win10 模块型号:quectel EC20 CE FAG 4G模块拨号步骤如下: 1. 打开网络和internet设置 2. 选择“拨号” 3. 选择“设置新连接” 4. 选择“拨号调至 ...

  4. (转)打印相关_C#(PrintDocument、PrintDialog、PageSetupDialog、PrintPreviewDialog)

    原文地址:http://www.cnblogs.com/smallsoftfox/archive/2012/06/25/2562718.html 参考文章:http://www.cnblogs.com ...

  5. NUMA的取舍与优化设置

    在os层numa关闭时,打开bios层的numa会影响性能,QPS会下降15-30%; 在bios层面numa关闭时,无论os层面的numa是否打开,都不会影响性能. 安装numactl:      ...

  6. solr 使用edismax来控制评分

    如何控制评分 如果设置了sort字段,那么将会按照sort字段的顺序返回结果. 如果没有设置sort字段,那么将会根据相关度打分来排序.也就是说,相关度更高的排在前面. 如何来定制适合自身业务的排序打 ...

  7. linux命令之vi文本编辑器

    vi filename :打开或新建文件,并将光标置于第一行首 按i,开始输入(insert) d删除整行 u   撤销上一步的操作Ctrl+r 恢复上一步被撤销的操作 ESC退出输入 按ESC键 跳 ...

  8. 爬虫概念 requests模块

    requests模块 - 基于如下5点展开requests模块的学习 什么是requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能 ...

  9. python-初始化函数

    #本次学习:初始化函数 #-*- coding:utf-8 -*- class SeniorTestingEngineer: #初始化函数,在创建对象的时候就设置初始值.例如我们在SeniorTest ...

  10. WPF 操作XML 读写

    来自:http://blog.sina.com.cn/s/blog_633d0e170100xyc6.html XML(可扩展标记语言) 定义:用于标记电子文件使其具有结构性的标记语言,可以用来标记数 ...