关于结构数据“获取”的表现

时间:2014-01-29 05:42:49

标签: c++ c performance

考虑到从给定结构中“获取”数据的两种可能方法,我对性能影响有疑问。假设'name'变量与'id'的值相关。

假设我有一个结构和枚举如下,

enum GenericId { NONE, ONE, TWO };

struct GenericTypeDefinition {
    GenericId id;
    const char name[8];
    ...
};

假设我想获得此结构的名称。很简单,我可以只引用GenericTypeDefinition结构的实例并引用(或指向)名称成员。很简单。

现在,这是我的表现问题变得相关的地方。说我需要创建数百个这样的实例,所有这些实例都将被锁定为一定数量的名称和唯一的id。这些实例将被称为整个程序中可能的“GenericTypeDefinition”的集合。请记住,'name'的值相对于'id'的值。我的问题是,如果我实现了如下的函数(并从结构中删除了name变量),我是否能够保存一些内存,

struct GenericTypeDefinition { // 'name' is now removed.
    GenericId id;
    ...
};

const char* Definition_ToString(GenericEnum e) {
    switch (e) {
        case NONE: return "Nothing";
        case ZERO: return "Zero is not nothing.";
    ...
}

我认为这是因为我释放了在我创建的每个结构中存储字符串(长度为8个字节)的需要。

如果您想要任何澄清,请询问,因为我在这方面找不到多少。

4 个答案:

答案 0 :(得分:1)

如果我理解了您的要求,那么您将把冗余数据放入结构中。基本上,您可以从结构中的id获取结构的名称。但是,您也可以将名称直接存储在结构中。

所以,你是对的 - 不存储名称将节省内存,因为你不会存储每个项目的名称。费用是一点时间。您需要调用一个函数,以便在每次需要时从id中为您提供名称。您将不得不权衡这些权衡以确定哪个更重要。

答案 1 :(得分:1)

魔鬼在细节上。答案取决于很多事情。例如,分配此类结构的频率,使用频率以及char name[8];的使用频率。

如果从结构中删除name,可能会发生以下几种情况:

  • 如果你有很多这种类型的对象和一个好的分配器,你将节省空间。
  • 如果您在某些演算期间广泛使用这些对象,并且您不时只使用name,那么由于更好的缓存性能,您将节省时间。
  • 如果您使用name进行大量计算,而且您的函数Definition_ToString只比示例中的函数稍微复杂一点,那么您的性能就会松懈。

然而,根据我的估计,这样的优化只能通过一些小因素加速程序。当您以微秒计数时,它可能会有所帮助。如果您的程序非常慢,请寻找渐近更好的算法。

答案 2 :(得分:0)

在大多数情况下,编译器会为您完成这项工作。它通常将所有const字符串文字存储在可执行文件的RO部分中。根据优化级别,它甚至可以消除结构中char数组占用的内存。所以你的可执行文件大小会增长,但它不会影响运行时内存。 但是,由于名称与ID绑定,从逻辑上讲,实现第二个版本是有意义的,因此将来如果要添加新ID,则不需要执行任何冗余工作。

答案 3 :(得分:0)

在你的第一种情况下,使用正确的ID和NAME初始化结构的任务意味着程序在一开始就复制文字,这就是字符串(因为我假设您使用代码中的字符串初始化结构)到RAM内存中的另一个空间, char [] 将指向该空间。

相反,第二种情况意味着从程序本身读取值(文字在深度汇编程序代码中的某个表中硬编码),并将返回指向它的指针(如果指针不是,则纠正我)在程序的某个地方,但返回的const char *存储为变量),因此你确实节省了一些内存。

我的个人评论(您可能会在问题的范围之外看到它),即使第二种选择可能会为您节省一些记忆,也意味着ID和NAME是硬编码,因此离开在运行期间任何扩展的可能性(即你想要添加更多通过控制台收到的ID ......)。