考虑到从给定结构中“获取”数据的两种可能方法,我对性能影响有疑问。假设'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个字节)的需要。
如果您想要任何澄清,请询问,因为我在这方面找不到多少。
答案 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 ......)。