代码之家  ›  专栏  ›  技术社区  ›  Enriquev

C类结构的“开销”?

  •  14
  • Enriquev  · 技术社区  · 15 年前

    我正在进行3354课程(在.NET Framework 2.0中实现系统类型和接口),据说对于具有成员变量和函数的简单类,由于开销的原因,使用结构比使用类更好。

    我从来没有听说过这样的事情,这个主张的有效性是什么?

    11 回复  |  直到 13 年前
        1
  •  12
  •   user166390    15 年前

    我建议 从不使用结构 除非你有一个非常具体的用例 确切地知道结构如何使系统受益 .

    虽然C结构允许成员,但它们的工作方式与类有很大的不同(不能是子类型,没有虚拟分派, 可以 完全依赖堆栈)和行为的变化取决于提升等(提升是将值类型提升到堆栈的过程——惊喜!)

    因此,要回答这个问题:我认为C中最大的误称之一是使用结构“来实现性能”。原因是,如果不看它如何与系统的其余部分以及它所扮演的角色(如果有什么值得注意的话)进行交互,就无法真正衡量“开销”。这需要分析,不能用“更少的开销”这样一个简单的语句来总结。

    有一些 好的 结构值类型的例子——一个例子是存储在图像数组中的复合RGB值。这是因为RGB类型很小,可以 非常 在一个图像中,值类型可以很好地打包在数组中,并且有助于保持更好的内存位置等。

        2
  •  9
  •   Mark Byers    15 年前

    出于性能原因,通常不应将应为类的类型更改为结构。结构和类具有不同的语义,不能完全互换。的确,结构有时可以更快,但有时也可以更慢。它们的行为方式不同,你应该认识到何时使用它们。

    msdn上有一页 choosing between classes and structures .

    总结如下:

    不要定义结构,除非 类型具有以下所有项 特点:

    • 它逻辑上表示一个值,类似于基元类型 (整数、双精度等)。
    • 它的实例大小小于16个字节。
    • 它是不变的。
    • 它不必经常装箱。

    有时,类型确实应该是类,但出于性能原因,您需要它是结构。这是罕见的,在走这条路之前,你应该确保你知道你在做什么。如果您违反了结构的不可变性准则,则可能会特别危险。可变结构可以以大多数程序员不期望的方式运行。

        3
  •  8
  •   John Källén    15 年前

    当C在beta中时,我接受了类和结构之间差异的演示。开发人员已经构建了一个Mandelbrot集查看器,它可以研磨许多复杂的数字来完成它的结果。在第一种情况下,他们使用复数运行代码,用实数和虚数字段表示类。然后,他们改变了这个词 class struct 并重新编译。性能差异很大。

    在这种情况下,不必分配堆对象,也不必对它们进行垃圾收集,这就是造成差异的原因。根据你有多少个物体,这种差异可能或多或少是惊人的。在开始调整之前,先测量性能,然后再决定是否使用值类型。

        4
  •  2
  •   Pierreten    15 年前

    你要用95%的时间上课。值类型语义最终会比不顺路更经常地咬你屁股。

    但是,如果要使用结构,请确保它是不可变的。

        5
  •  1
  •   Ben.Vineyard    15 年前

    在C中,类和结构是完全不同的动物。两种语言的语法几乎相同,但其行为完全不同(引用与值)。结构的单个实例将比等效类使用更少的内存,但一旦开始构建集合或传递集合,值类型语义将在性能方面(以及可能的内存消耗,具体取决于您所做的工作)杀死您,除非结构中的数据非常小。我不知道硬数字是什么,但我们谈论的是8字节或更少的顺序。

    在可维护性和可读性方面,它也会受到损害,因为这两者看起来非常相似,但行为却如此不同。

        6
  •  1
  •   Igor Zevaka    15 年前

    你可以遵循的一条经验法则是问问自己 不管你想做什么 System.Date 如果不是,那么您真的应该质疑您使用结构的决定。

        7
  •  0
  •   zerkms    15 年前

    结构是值类型,类是引用类型。这可能是原因之一。

        8
  •  0
  •   Gabe Timothy Khouri    15 年前

    对于简单类型,如果您将拥有其中许多类型,则不需要继承,并且是不可变的很好的候选者,结构是一个不错的选择。例如,点、矩形、小数和日期时间。

    如果你不会有很多,那么开销是不相关的,它不应该影响你的决定。如果您需要从它派生(或使它成为派生类型),它必须是一个类。如果项不能是不可变的,那么struct不是一个好的候选者,因为改变一个实例不会改变它的任何副本。

        9
  •  0
  •   Thorarin    15 年前

    我相信最常用的盈亏平衡点是结构中大约12字节的数据。例如,3个整数。但是,值类型和引用类型之间的区别更为基本,您应该根据成员较少的类型来选择。

    如果有什么大的,那么类:)

        10
  •  0
  •   Eric Mickelsen    15 年前

    结构是值类型,类是引用类型。因此,如果您要传递引用,那么类的性能会更好,因为您复制的是一个地址而不是整个结构。但是,如果要多次实例化和引用这些对象,那么结构的性能会更好,因为它们是在堆栈上分配的。因此,对于性能很重要的许多对象或需要值类型语义的小型对象,结构可能更好。结构也没有默认的构造函数。它们确实是从对象继承的,但除此之外,它们是自由继承的。

        11
  •  -1
  •   Loren Pechtel    15 年前

    不需要分配/解除分配结构。