Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与';获得';结构数据的存储_C++_C_Performance - Fatal编程技术网

C++ 与';获得';结构数据的存储

C++ 与';获得';结构数据的存储,c++,c,performance,C++,C,Performance,在考虑从给定结构“获取”数据的两种可能方法时,我有一个关于性能影响的问题。假设“name”变量与“id”的值有关 假设我有一个结构和枚举,如下所示 enum GenericId { NONE, ONE, TWO }; struct GenericTypeDefinition { GenericId id; const char name[8]; ... }; 假设我想得到这个结构的名称。非常简单,我可以引用GenericTypeDefinition结构的实例并引用(或

在考虑从给定结构“获取”数据的两种可能方法时,我有一个关于性能影响的问题。假设“name”变量与“id”的值有关

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

enum GenericId { NONE, ONE, TWO };

struct GenericTypeDefinition {
    GenericId id;
    const char name[8];
    ...
};
假设我想得到这个结构的名称。非常简单,我可以引用GenericTypeDefinition结构的实例并引用(或指向)名称成员。很简单

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

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


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

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


因此,您是对的——不存储名称将节省内存,因为您不会将名称与每个项目一起存储。花费的时间有点长。每次需要时,您都需要调用一个函数,从id中获得名称。您必须权衡这些权衡,以确定哪个更重要。

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

在第一种情况下,使用正确的ID和名称初始化结构的任务意味着程序将在一开始将文本(即字符串)复制到RAM内存中的另一个空间,char[]将指向该空间

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


我个人的意见是(您可能会认为这超出了问题的范围),即尽管第二个备选方案可能会为您节省一些内存,但这意味着ID和名称是硬编码的,因此在运行时不存在任何扩展的可能性(即,您希望添加更多通过控制台接收的ID…).魔鬼在细节中。答案取决于很多事情。例如,这种结构的分配频率、使用频率以及
char name[8]的频率被使用

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

  • 如果您有许多这种类型的对象和一个好的分配器,您将节省空间
  • 如果您在某些微积分过程中广泛使用这些对象,并且仅偶尔使用
    name
    ,那么由于缓存性能更好,您将节省时间
  • 如果在某些计算中大量使用
    name
    ,而函数
    Definition\u-ToString
    比示例中的函数稍微复杂一点,则会降低性能

然而,据我估计,像这样的优化只会使程序加快一小部分。在以微秒为单位计数的情况下,它可能会有所帮助。如果您的程序非常慢,请寻找渐进更好的算法。

谢谢您的回复,我非常感谢。
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.";
    ...
}