对象创建开销是否适用于结构?
Does object creation overhead apply to structs?
我要的是 C# 项目,但我想这个问题也适用于其他语言。我听说大量的对象创建和销毁会导致大量的开销和性能问题。我想知道我是否可以通过简单地使用结构而不是对象来解决这个问题。
"Making struct instead of object" - 如您所说(我想您所说的 object 是 class)由于结构的性质,创建结构实例将很可能没有什么帮助,将要求您通过值而不是通过引用来引用它 - 而这 可能 (并非总是)使您内存使用 更重
也就是说,您可能需要的是享元设计模式
来自https://sourcemaking.com/design_patterns/flyweight:
享元设计模式
意图
使用共享有效地支持大量细粒度对象。
用轻量级小工具替换重量级小工具的 Motif GUI 策略。
问题
将对象设计到系统的最低级别 "granularity" 提供了最佳的灵活性,但在性能和内存使用方面可能会非常昂贵。
讨论
Flyweight 模式描述了如何共享对象以允许在没有高昂成本的情况下以精细的粒度使用它们。每个 "flyweight" 对象分为两部分:状态相关(外部)部分和状态无关(内部)部分。内部状态存储(共享)在享元对象中。外部状态由客户端对象存储或计算,并在调用其操作时传递给享元。
以下是关于 C# 中 struct
和 class
的一些事实:
- C# 中的
struct
比 class
的创建速度更快,因为它分配在堆栈上而不是堆上
struct
是值类型,class
是引用类型。因此,使用引用类型(将其作为参数传递、复制它……)比使用值类型要快得多。见 Difference between struct and class
struct
字段比 class
字段访问速度快,因为它们是在堆栈上分配的
以下是有关 .Net 中 GC 工作原理的一些事实:
- 您无法控制 CLR 何时触发 GC,它可以随时中断您的程序(您可以使用一些选项来告诉 CLR 您正在 运行代码的敏感部分,但如果需要内存,它不会阻止 GC 运行。参见 GC Latency Modes)
- 您无法控制 GC 完成工作所需的时间
- 当 GC 进行完整收集时,它会冻结所有程序线程(取决于您是处于 gcConcurrent 还是 gcServer 模式,请参阅 gcServer mode)。
了解所有这些,简而言之,如果您不希望您的程序受到 GC 工作的影响,您必须为将在程序中存活更长时间的对象使用引用类型,并使用值类型对于将在非常短的时间内和非常局部的范围内使用的对象。
我要的是 C# 项目,但我想这个问题也适用于其他语言。我听说大量的对象创建和销毁会导致大量的开销和性能问题。我想知道我是否可以通过简单地使用结构而不是对象来解决这个问题。
"Making struct instead of object" - 如您所说(我想您所说的 object 是 class)由于结构的性质,创建结构实例将很可能没有什么帮助,将要求您通过值而不是通过引用来引用它 - 而这 可能 (并非总是)使您内存使用 更重
也就是说,您可能需要的是享元设计模式
来自https://sourcemaking.com/design_patterns/flyweight:
享元设计模式
意图
使用共享有效地支持大量细粒度对象。
用轻量级小工具替换重量级小工具的 Motif GUI 策略。
问题
将对象设计到系统的最低级别 "granularity" 提供了最佳的灵活性,但在性能和内存使用方面可能会非常昂贵。
讨论
Flyweight 模式描述了如何共享对象以允许在没有高昂成本的情况下以精细的粒度使用它们。每个 "flyweight" 对象分为两部分:状态相关(外部)部分和状态无关(内部)部分。内部状态存储(共享)在享元对象中。外部状态由客户端对象存储或计算,并在调用其操作时传递给享元。
以下是关于 C# 中 struct
和 class
的一些事实:
- C# 中的
struct
比class
的创建速度更快,因为它分配在堆栈上而不是堆上 struct
是值类型,class
是引用类型。因此,使用引用类型(将其作为参数传递、复制它……)比使用值类型要快得多。见 Difference between struct and classstruct
字段比class
字段访问速度快,因为它们是在堆栈上分配的
以下是有关 .Net 中 GC 工作原理的一些事实:
- 您无法控制 CLR 何时触发 GC,它可以随时中断您的程序(您可以使用一些选项来告诉 CLR 您正在 运行代码的敏感部分,但如果需要内存,它不会阻止 GC 运行。参见 GC Latency Modes)
- 您无法控制 GC 完成工作所需的时间
- 当 GC 进行完整收集时,它会冻结所有程序线程(取决于您是处于 gcConcurrent 还是 gcServer 模式,请参阅 gcServer mode)。
了解所有这些,简而言之,如果您不希望您的程序受到 GC 工作的影响,您必须为将在程序中存活更长时间的对象使用引用类型,并使用值类型对于将在非常短的时间内和非常局部的范围内使用的对象。