前言

在内存当道的日子里,无论什么时候都要考虑这些代码是否会影响程序性能呢?
在现在的世界里,几乎不会去考虑用了几百毫秒,可是在特别的场景了,往往这几百毫米确影响了整个项目的快慢。
通过了解这两者之间的性能差异,希望帮助大家在合适的场景里选择正确的编码。

实例

Copy

public class PointClass
{
public int X { get; set; }
public int Y { get; set; }
public PointClass(int x, int y)
{
X = x;
Y = y;
}
}

public class PointClassFinalized : PointClass
{
public PointClassFinalized(int x, int y) : base(x, y)
{
}
~PointClassFinalized()
{

}
}

public struct PointStruct
{
public int X { get; set; }
public int Y { get; set; }
public PointStruct(int x, int y)
{
X = x;
Y = y;
}
}

public class StructsTest : PerformanceTest
{
protected override bool MeasureTestA()
{

var list = new PointClassFinalized[Iterations];
for (int i = 0; i < Iterations; i++)
{
list[i] = new PointClassFinalized(i, i);
}
return true;
}

protected override bool MeasureTestB()
{

var list = new PointClass[Iterations];
for (int i = 0; i < Iterations; i++)
{
list[i] = new PointClass(i, i);
}
return true;
}

protected override bool MeasureTestC()
{

var list = new PointStruct[Iterations];
for (int i = 0; i < Iterations; i++)
{
list[i] = new PointStruct(i, i);
}
return true;
}
}

有一个PointClass和一个 PointStruct
,这两者用于存放X 和Y 两个变量,而且还有一个 PointClassFinalized

方法 MeasureTestA 创建了100万个 PointClassFinalized 实例

方法 MeasureTestB 创建了100万个 PointClass 实例

方法 MeasureTestC 创建了100万个 PointStruct 实例

您认为哪种方法最快?

MeasureTestB 和 MeasureTestC 这两个方法的唯一不同在于一个是创建类 一个是创建结构。

MeasureTestC 仅在17毫秒内完成分配并运行,比 MeasureTestB 方法快8.6倍!

为什么会出现这样的事情,这里发生了什么?

不同的在于结构和类如何存储在内存中。

下面是 PointClass 实例 内存布局:

该列表是一个局部变量,存放在堆栈中。引用堆上的一组 PointClass实例

PointClass 是一个引用类型,存放在堆上。

该列表仅维护一个数组,指向存储在堆上 PointClass 实例。

观察到上图的黄色箭头,在堆上引用了很多实例。

数组是一组相同的对象,MeasureTestB 这个方法是将一组相同的对象存放在数组中。

当访问指定数组元素时,.NET运行时需要检索对象引用,然后“跟随”引用以获取PointClass实例。

当数组元素超出范围时,.NET垃圾收集器就会开始回收PointClass对象内存,在 MeasureTestA 方法中 的PointClassFinalized类 其实增加了额外时间。

.NET Framework在单个线程上运行所有终结器,线程必须在垃圾回收器可以回收内存之前依次处理1,000,000个对象。

可以看到MeasureTestAMeasureTestB慢1.7倍。

我们来看看 PointStruct 的内存布局:

结构是值类型,所有 PointStruct 实例都存储在数组本身中。堆上只有一个对象。

初始化数组,.NET运行库可以将X和Y值直接写入数组里。无需在堆上创建新对象,也不需要引用它。

当访问指定数组元素时,.NET运行时可以直接检索结构。

当超出范围时,.NET垃圾回收器只需要处理单个对象。

总结

我们总要使用结构吗?要分情况看:

  • 当您存储超过30-40个字节的数据时,请使用类。

  • 存储引用类型时,请使用类。

  • 当您存储多于几千个实例时,请使用类。

  • 如果列表是长的生命周期的,请使用类。

  • 在所有其他情况下,使用结构。

原文:https://www.cnblogs.com/luquanmingren/p/11263161.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

C#中谁最快:结构还是类?相关推荐

  1. c#中结构与类的区别

    类与结构的差别 如何选择结构还是类 一.类与结构的示例比较: 结构示例: public struct Person  { string Name; int height; int weight pub ...

  2. C#中的结构和类之间的区别

    C#类和结构 (C# class and structure) In C# and other programming languages, structure and classes are use ...

  3. VC++和VC++.NET中与图像处理有关的几个概念、结构和类

    VC++和VC++.NET中与图像处理有关的几个概念.结构和类 最近一直在看VC++有关图像处理方面的书,终于把以前一直混淆的几个概念.结构和类弄清楚了,特整理如下.如有错误,请大家批评指正,不胜感激 ...

  4. c#中结构与类的区别(转)

    目录 类与结构的实例比较<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" / ...

  5. [转载]:C# 中结构与类的区别

    转载自:http://www.cftea.com/c/2008/03/JHB3MJM8DYGS0JJ9.asp 完美集成.增强 KindEditor HTML 编辑器 目录 类与结构的实例比较 类与结 ...

  6. html中结构伪类选择器,结构伪类选择器

    属性选择器 元素的属性,我们都知道是什么.例如下面代码中type和value就是input元素的属性.属性选择器,顾名思义,就是通过属性来选择元素的一种方式. 属性选择器 说明 E[attr^=&qu ...

  7. Intellij IDEA展示类中的方法树形结构

    在intellij Idea中叫Structure(结构体),如下图: 也可以直接Alt+F7快捷键,这样默认会把Structure显示在屏幕下方,如下图操作就可以移动到右侧. 效果如下:

  8. 用java设计一个二叉树类的结构,在JAVA中实现的二叉树结构

    在JAVA中实现的二叉树结构 [日期:2008-12-16] 来源:IT专家网 作者:竹一 [字体:大 中 小] * * 讲解: * 二个方法函数,一个寻找关键字--searchkey 另一个是插入一 ...

  9. python 类的执行中保部存值_c/c++关于内存分配的知识(非常详细的比较,且VirtualAlloc分配内直接在进程的地址空间中保留一快内存)...

    一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一 ...

最新文章

  1. 只有程序员才有的十大烦恼
  2. 九度互动社区IT名企招聘上机考试热身赛
  3. 【学生信息管理系统】——优化篇(一)
  4. tooltip.css-2.0文档
  5. 趣挨踢 | 那些出现在电影或电视剧中的精彩代码,你认出来几个?
  6. SqlServer2008备份与还原(完整图示版)
  7. 有助于获得优质流量的免费SEO关键词工具
  8. Python创建进程、线程的两种方式
  9. 开源硬件 专利_标准和开源:为什么专利待遇不同?
  10. [转载] python价值算法_PangRank算法原理及其Python实现
  11. jQuery打造智能提示插件
  12. cefsharp 二次开发
  13. C语言中实现字符串的拼接
  14. iOS- 添加UIWindow蒙版
  15. 华为手机安装debug时出现无效安装和与操作系统不兼容问题解决
  16. 乔布斯斯坦福毕业演讲,这是我听过最精彩的毕业演讲!
  17. 微软live服务器地址,在Mail中设置windows Live hotmail方法
  18. i标签和em标签的区别
  19. 一种用几何解nonlinear ICA的方法
  20. 遍历文件夹(含子文件夹)方法

热门文章

  1. 如何在Windows中快速轻松地将文件发送到SkyDrive
  2. Comcast以纯文本泄露客户Wi-Fi登录信息,立即更改密码
  3. python博客访问量_史诗级干货-python爬虫之增加CSDN访问量
  4. linux下tomcat开启远程调试
  5. Python中文编码判别及转换
  6. CentOS 5.6 快速搭建LAMP
  7. 如何使用windbg查看C#某个线程的栈大小 ?
  8. Avalonia跨平台入门第二篇
  9. C#中类的override和virtual
  10. 【Blog.Core开源】网关统一集成下游服务文档