0

凭借我目前拥有的所有知识,我无法决定将哪个用于我的用例。

现在这是 struct 的示例。

第一堂课看起来像这样:

class Owner
{
  public A[] Kids;

  public Owner(int count)
  {
    Kids = new A [count];

    // If I would use classes I would need to create new class for each item, right?
    // It would look like below and my worries are memory impacts because of new A()
    // for(int i = 0; i < count; Kids[i++] = new A());
  }
}

第二个类看起来像这样:

class Node
{
  private Owner o;
  private int num;
  private A[] kids;

  public Node(Owner o, int num)
  {
   this.o = o;
   this.num = num;
  }

  public A[] Kids
  {
    get
    {
      this.kids = o.Kids[num].NextList;
      return this.kids;
    }
  }
}

A型看起来像这样

<struct or class> A
{
  public int Value;
  public A[] NextList;
}

现在的问题是,使用结构时访问会比使用类时运行得更快吗?

使用类时我会得到内存开销,因为我需要初始化每个类。

使用类时我需要注意杀死引用吗?

在这种情况下,你会使用哪个家伙?

如果这是重复的或者我做错了什么,我深表歉意。请在降级问题之前告诉我我做错了什么。我还是这个论坛的新手。

4

1 回答 1

1

TL;DR:使用类。

由于您使用的是数组并且您担心内存,因此需要记住一件事:

如果您有一个结构数组,那么为该数组分配的总字节数将为sizeof(your struct) * number of elements

如果您有一个类数组,那么为该数组分配的总字节数将为sizeof(reference) * number of elements(其中引用的大小对于 x86 为 32 位,对于 x64 为 64 位)。

在某些情况下,这可能会产生很大的不同。

如果数组的总大小超过 85,000 字节,那么它将被放置到大对象堆中。否则,它会进入普通堆。这可能意味着使用结构会导致某些数组超过 85,000 字节的阈值,而如果您使用类,它们将不会达到该阈值。

大对象堆上的项目在垃圾收集 (*) 期间不会被压缩,因此如果您有太多大对象,您可能会遇到内存碎片问题。

请注意,这也适用于许多其他集合(例如List<T>),因为它们在实现中使用数组。

在大多数情况下,使用类而不是结构的开销可以忽略不计,无论如何,如果您认为它会导致问题,您应该确定代码。

因此,您通常应该只使用一个类。

还有一点需要注意:

如果您有一个结构列表,则无法更改列表中单个元素的属性,除非用更新的元素替换整个元素。

所以这是不可能的:

List<MyStruct> list = new List<MyStruct>();
... init list
list[0].Value = 1; // Compile error for structs, no error for classes.

但这不应该是一个问题——因为你的结构总是不可变的,所以你不会一开始就尝试这样做,对吧?;)


(*) 这不再严格意义上的正确了。.Net 4.51 引入了一种允许下一次垃圾收集移动大对象的方法,但这必须以编程方式启动。

http://blogs.msdn.com/b/mariohewardt/archive/2013/06/26/no-more-memory-fragmentation-on-the-large-object-heap.aspx

于 2013-09-27T11:17:49.967 回答