【问题标题】:How to avoid padding in a C++ object?如何避免在 C++ 对象中填充?
【发布时间】:2016-07-17 23:15:55
【问题描述】:

我有一个类,我想重新组织它以避免填充 我怎样才能做到这一点? 我应该担心函数顺序吗?

班级是:

class MyClass
{
    private:
    std::vector<std::pair<char,MyClass>> fils;
    std::string etiquette = "";
    unsigned int frequence = 0;

    void privateFunction1();
    void privateFunction2();
    void privateFunction3();

    public:
    MyClass();

    void publicFunction1();
    void publicFunction2();
    void publicFunction3();
};

【问题讨论】:

  • 为什么要避免填充?填充是一种特性,而不是敌人。
  • 除非您的目标是内存紧张的嵌入式系统(内存以几千字节为单位),否则我建议您不要打扰。填充可以使结构在内存中更好地对齐,从而可能导致更快的访问时间。
  • 你可以通过不同的方式打包结构来改变对齐和填充(当然也可以通过重新排列成员变量)。如何做到这一点取决于您使用的编译器。这可能会为您的课程节省几个字节,但它不会是“递归的”。 std::vectorstd::string 类中的填充不会改变。
  • 另外,fils 元素真的应该是一对字符和类的 instance 吗?这会复制整个对象。也许您应该改用指针?这可能会为您节省很多,具体取决于您的用例或课程。可能比尝试打包课程更好。
  • 成员函数在对象中不占用空间(除非它们是virtual),因此重新排序它们并不重要,只有变量。使用使用sizeof 打印不同变体大小的测试程序。对于打包,如果您告诉编译器打包MyClass 结构,那么只会打包该结构。反过来结构的成员变量将不会被打包。因此,您可以在filsetiquettefrequence 之间节省几个字节的填充,仅此而已。 std::vectorstd::string 结构不会被打包。

标签: c++ class optimization memory-management padding


【解决方案1】:

正如评论中已经提到的,函数的功能和顺序对于大小并不重要。

MyClass 结构本身确实不应该有任何填充(或者至少在 32 位系统上不应该,但你没有提到 cpu 架构),但是 std::vector 和 std::string 的内容是在类的实际结构之外分配。

正如您在this answer 中看到的那样,向量的内容在您向向量中添加数据时分配的连续内存中,除非您设置容量,否则可能会有很多开销——所以@987654322 @ MyClass 中的 std::vector 数据可能会增加额外的开销。

消除填充可以为您节省任何东西的唯一结构是std::pair&lt;char, MyClass&gt; .. 您并没有说 std::vector 中有多少元素,但如果几乎每个可能的字符都有一个元素(即几乎 256),并且由于您担心总内存消耗,那么您最好使用 a

 MyClass *fils[256];

而不是

 std:vector< std:pair<char, MyClass> > fils

因为您不再需要管理向量的容量来获得确切的空间,并且填充后的开销与 std::pair 大致相同。

此外,我的系统上空 std::string 的开销是 32 个字节,因此根据您在 etiquette 中保留的内容,您可能还需要重新考虑这一点——例如,如果 etiquette 在MyClass 的不同实例是重复的,您可能希望找到一种方法来保留一组唯一的值,并且只是从 MyClass 指向唯一的 etiquette

YMMV.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多