C#中谁最快:结构还是类?

简介: C#中谁最快:结构还是类?前言#在内存当道的日子里,无论什么时候都要考虑这些代码是否会影响程序性能呢?在现在的世界里,几乎不会去考虑用了几百毫秒,可是在特别的场景了,往往这几百毫米确影响了整个项目的快慢。

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

实例#
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()
{
    // added a finalizer to slow down the GC

}

}

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()
{
    // access array elements
    var list = new PointClassFinalized[Iterations];
    for (int i = 0; i < Iterations; i++)
    {
        list[i] = new PointClassFinalized(i, i);
    }
    return true;
}

protected override bool MeasureTestB()
{
    // access array elements
    var list = new PointClass[Iterations];
    for (int i = 0; i < Iterations; i++)
    {
        list[i] = new PointClass(i, i);
    }
    return true;
}

protected override bool MeasureTestC()
{
    // access array elements
    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个对象。

可以看到MeasureTestA比MeasureTestB慢1.7倍。

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

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

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

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

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

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

当您存储超过30-40个字节的数据时,请使用类。
存储引用类型时,请使用类。
当您存储多于几千个实例时,请使用类。
如果列表是长的生命周期的,请使用类。
在所有其他情况下,使用结构。
相关链接:#
destructors
classes-and-structs
medium
作者:androllen

出处:https://www.cnblogs.com/luquanmingren/p/11263161.html

相关文章
|
8月前
|
算法 C++ 容器
关系类算法函数
关系类算法函数
|
10月前
|
编译器 C语言 C++
C++ 之什么是类 & 对象的关系?
C++ 之什么是类 & 对象的关系?
|
设计模式 存储 前端开发
层次结构及对象的定义|学习笔记
快速学习层次结构及对象的定义
100 0
|
存储 Java
类与类的关系
## 继承关系 1.子类想要继承父类,通过extends关键字来实现 2.子类继承了父类,可以调用父类中(public protected)的属性和方法 2.1构造方法严格意义来说 不算做子类继承过来 只是单纯的在子类调用构造方法时默认调用父类的构造方法 2.2程序块严格意义来说 不算做子类继承过来(子类自己调用不到 没名字) 程序块子类不能直接调用 子类执行构造方法之前 默认调用了父类的构造方法 父类构造方法之前自动执行父类的块 3.子类除了能继承父类的属性和方法外,子类还可以添加自己独有的成员(属性 方法)
92 0
类的结构分析 下
1.class_getInstanceMethod : 获取实例方法, 如果指定类或其父类不包含带有指定选择的实例方法, 则为NULL. 2.class_getClassMethod : 获取类方法, 如果指定类或其父类不包含具有指定的类方法, 则为NULL. 3.class_getMethodImplementation : 获取方法的具体实现, 如果未查找到, 则进行消息转发.
97 0
类的结构分析 下
|
存储
类的结构分析
我们来分析类的结构: 先引入一个列子,(注意以下代码是在objc源码中调试的): 例子说明: CJLPerson继承于NSObject, CJLTeacher继承于CJLPerson
101 0
类的结构分析
|
存储 开发者 Python
对象的结构|学习笔记
快速学习 对象的结构
101 0
|
C#
C#中的结构与类
C#中的结构与类
123 0
#掌握如何创建类和对象,以及属性和函数的分类 #object是所有类最终都会继承的类,如果没有合适的继承类就使用他
#掌握如何创建类和对象,以及属性和函数的分类 #object是所有类最终都会继承的类,如果没有合适的继承类就使用他
|
Java 开发者
反射获取类结构信息|学习笔记
快速学习反射获取类结构信息
108 0
反射获取类结构信息|学习笔记

热门文章

最新文章