将 class 的成员重构为结构容器时是否有性能考虑?
Are there performance considerations when refactoring members of a class into a struct container?
假设我有几个这样的 class:
class MyClassA {
public List<string> UpData;
public List<string> DownData;
public List<string> LeftData;
public List<string> RightData;
}
class MyClassB {
public List<string> UpData;
public List<string> DownData;
public List<string> LeftData;
public List<string> RightData;
}
我想重构它们以便我可以添加一些方便的东西(比如枚举器,或者有一些让我选择特定成员的函数):
struct DirectionMap {
public List<string> Up;
public List<string> Down;
public List<string> Left;
public List<string> Right;
//... various helper functions ...
}
class MyClassA {
public DirectionMap Data;
}
class MyClassB {
public DirectionMap Data;
}
但是,我的应用程序非常占用内存,而且我有数百万个此类实例,因此我需要牢记内存使用和垃圾收集。我还必须尽可能频繁地改变这些对象,所以速度也很重要。这样做有任何性能开销吗?
如果我理解正确,如果 DirectionMap
是一个 class,它会使用更多的内存来存储指向它的指针,并额外接触堆,对吗?但它作为一个结构是免费的吗?
我知道结构中的可变对象可能会导致错误,但我不打算传递 Data
,只传递它包含的字符串列表,这些是参考值。
谈论性能时的第一条规则是分析代码,即使是经验丰富的开发人员也可能对需要时间的事情感到惊讶。
如果将内容放在结构中与直接放在 class 中,我希望内存使用和性能是相同的。内存布局应该相似或相同。
除非您非常小心,否则我不建议更改结构。 IE。替换 Up-list 的内容会很好,但是用新列表替换 Up-list 可能会导致问题。参见 Why mutating structs are evil。
如果您为结构实现接口,则需要注意装箱。如果您实现 IEnumerable<List<string>>
并使用任何 linq 方法,这将导致结构为 boxed, not ideal for performance. This should be possible to avoid by using generic constraints. You might also want to use a readonly struct and the and the in parameter modifier 以避免复制。例如:
public static void MyMethod<T, U>(in T value) where T : struct, IEnumerable<U>
{
// do something
}
假设我有几个这样的 class:
class MyClassA {
public List<string> UpData;
public List<string> DownData;
public List<string> LeftData;
public List<string> RightData;
}
class MyClassB {
public List<string> UpData;
public List<string> DownData;
public List<string> LeftData;
public List<string> RightData;
}
我想重构它们以便我可以添加一些方便的东西(比如枚举器,或者有一些让我选择特定成员的函数):
struct DirectionMap {
public List<string> Up;
public List<string> Down;
public List<string> Left;
public List<string> Right;
//... various helper functions ...
}
class MyClassA {
public DirectionMap Data;
}
class MyClassB {
public DirectionMap Data;
}
但是,我的应用程序非常占用内存,而且我有数百万个此类实例,因此我需要牢记内存使用和垃圾收集。我还必须尽可能频繁地改变这些对象,所以速度也很重要。这样做有任何性能开销吗?
如果我理解正确,如果 DirectionMap
是一个 class,它会使用更多的内存来存储指向它的指针,并额外接触堆,对吗?但它作为一个结构是免费的吗?
我知道结构中的可变对象可能会导致错误,但我不打算传递 Data
,只传递它包含的字符串列表,这些是参考值。
谈论性能时的第一条规则是分析代码,即使是经验丰富的开发人员也可能对需要时间的事情感到惊讶。
如果将内容放在结构中与直接放在 class 中,我希望内存使用和性能是相同的。内存布局应该相似或相同。
除非您非常小心,否则我不建议更改结构。 IE。替换 Up-list 的内容会很好,但是用新列表替换 Up-list 可能会导致问题。参见 Why mutating structs are evil。
如果您为结构实现接口,则需要注意装箱。如果您实现 IEnumerable<List<string>>
并使用任何 linq 方法,这将导致结构为 boxed, not ideal for performance. This should be possible to avoid by using generic constraints. You might also want to use a readonly struct and the and the in parameter modifier 以避免复制。例如:
public static void MyMethod<T, U>(in T value) where T : struct, IEnumerable<U>
{
// do something
}