在西山居的这篇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. SCCM2012 R2实战系列之九:OSD(中)--捕获镜像

    在上篇文章中我们详细的完成了OSD的初始化配置.导入镜像.任务序列的创建和常见问题的排错.但是在实际环境中这样分发了干净的操作系统后还需要手动为客户端安装各种各样的应用程序.所以更为好的方法是将一台计 ...

  2. matplotlib基础知识全面解析

    图像基本知识: 通常情况下,我们可以将一副Matplotlib图像分成三层结构: 1.第一层是底层的容器层,主要包括Canvas.Figure.Axes: 2.第二层是辅助显示层,主要包括Axis.S ...

  3. CRM stringmap

    CREATE view [dbo].[V_stringmap] as SELECT DISTINCT Entity.Name as tablename,StringMap.AttributeName ...

  4. C#存储过程中传入传出参数

    作者:卞功鑫  ,转载请保留http://www.cnblogs.com/BinBinGo/p/6399847.html //1 连接字符串 string connectionString = &qu ...

  5. 插件开发-滑条(slide)开发

    自己一直很喜欢开发组件,只是OPP学的不是很精,自己在项目中用别人的框架进行项目开发,难免受制于人,也许这就是个人实际项目需求和框架提供的多少有点不符,引导我自己尝试开发一些自己常用的组件,话不多说, ...

  6. Css实战第二天小结

    清除浮动的四种方式: 1.1    给父盒子设置一个高度: 1.2    Clear:both; 1.3    Overflow:hidden; 1.4    使用伪元素 .clearfix:befo ...

  7. Error running app: Default Activity not found ; 安卓程序运行不了,也不报错。

    我最近copy一个工程,写完了去运行时不能运行,项目不报错,就是运行的地方有个叉号:尝试很多办法后准备重新New一个时发现:"10:17 Error running app: Default ...

  8. [TJOI2015]弦论(后缀自动机)

    /* 一道在树上乱搞的题目 建立出parent树来, 然后就能搞出每个节点往后能扩展出几个串, 至于位置不同算同一个的话就强制让right集合大小为1即可 然后在树上类比权值线段树找第k大26分统计一 ...

  9. angularjs探秘<三> 控制器controller及angular项目结构

    先来看一个例子 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&quo ...

  10. ROS 进阶学习笔记(13) - Combine Subscriber and Publisher in Python, ROS

    Combine Subscriber and Publisher in Python, ROS This article will describe an example of Combining S ...