存储各种类型对象之间的许多 1:1 关系:解耦和高性能

2024-03-29

我有 300 多个课程。它们在某些方面是相关的。

为简单起见,所有关系均为 1:1。
这是一个示例图。

enter image description here (In real case, there are around 50 relation-pairs.)

Note:对于某些情况,某些关系可能不存在。
例如,一些hens 与任何都不相关food.

Note2:没有链接=从不,例如每一个egg与任何无关cage.
这种关系永远不会被添加/删除/查询。

问题:

如何优雅地保存它们之间的关系?
我的所有 4 个想法(如下)似乎都有缺点。

Here https://stackoverflow.com/questions/18501198/in-c-how-to-best-decouple-2-classes-that-must-maintain-collections-of-referenc是一个相关问题,但具有 1:N 并且只有 1 关系。

我糟糕的解决方案

这些是半伪代码。

版本 1 直接

我的第一个想法是互相添加指针)。

小鸡.h:-

class Egg;
class Food;
class Chick{  Egg* egg; Food* food;}

Hen.h:-

class Egg; class Cage; class Food;
class Hen{ Egg* egg; Cage* cage; Food* food;}

添加/删除关系和查询非常便宜,例如:-

int main(){
    Hen* hen;    ...    Egg* egg=hen->egg;
}

它工作得很好,但随着我的程序的增长,我想将它们解耦。
大致说来,Hen.h不应包含单词Egg,反之亦然。

有很多想法,但似乎没有一个很好。
我将展示每个解决方法的简短片段,然后在问题末尾总结优点和缺点。

版本 2 哈希映射

Use std::unordered_map.
它成为我的程序的瓶颈。 (在发布模式下进行分析)

class Egg{}; class Hen{};  //empty (nice)
.....
int main(){
    std::unordered_map<Hen*,Egg*> henToEgg;
    std::unordered_map<Egg*,Hen*> eggToHen;
    ....
    Hen* hen;    ...    Egg* egg=henToEgg[hen];
}

版本 3 Mediator-single

将每个实体的每个关系存储在一个大中介中。
为空插槽浪费大量内存(例如Egg has henFood_hen slot).
废物总量=type-of-relation-pair每个实体中*2*4 字节(如果以 32 位运行)。

class Mediator {
    Egg* eggHen_egg=nullptr;
    Hen* eggHen_hen=nullptr;
    Hen* henFood_hen=nullptr;
    Food* henFood_food=nullptr;
    //... no of line = relation * 2
};
class Base{public: Mediator m;};
class Egg : public Base{};  //empty (nice)
class Hen : public Base{}; 
int main(){
     Hen* hen;    ...    Egg* egg=hen->eggHen_egg;
}

版本 4 Mediator-array(与 3 类似)

尝试标准化——灵活性高。

class Mediator {
    Base* ptrLeft[5];
    Base* ptrRight[5];
};
class Base{public: Mediator m;};
class Egg : public Base{};  //empty (nice)
class Hen : public Base{}; 
int main(){
     enum RELA_X{RELA_HEN_EGG,RELA_HEN_CAGE,RELA_EGG_CHICK, .... };
     Hen* hen;    ...    
     Egg* egg=hen->m.ptrRight[RELA_HEN_EGG]; 
     //^ get right of "hen-egg" === get "egg" from "hen"
     //^ can be encapsulated for more awesome calling
}

优点缺点

Green (+) are good. Red (-) are bad. enter image description here

Edit:我在用实体组件 http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy对于 60fps 的游戏。
它是一个持久数据库:在游戏的整个生命周期中使用的单个实例。

Edit2:所有关系都是弱关系而不是is-a或强std::unique_ptr所有权。 (感谢沃尔特)

  • A hen is in a cage.
    Some hens不属于任何cage, 还有一些cages是空的。
  • A chick 来自 an egg.
    然而,一些chicks不来自任何egg(它们只是从天上掉下来的),
    还有一些eggs没有足够幸运成为chick.
  • A hen and a chick 正在吃一个(可能相同的)盘子food.
    Some food盘子刚刚准备好但还没有上桌。

Edit3:为每个对象分配一个整数 id 是一个好主意。
(感谢 Oliv、ahoxha 和 Simone Cifani)

Edit4::不需要提供可编译的代码,只需一个必要的部分/概念就足够了。


根据要求,如果只有一对一的关系,那么在我看来它就像一个图表。在这种情况下,如果它人口稠密(有很多关系),我会使用图的矩阵表示。在下表中,我将数字 0 到 4 分别与实体(母鸡、笼子、食物、鸡蛋和小鸡)相关联。如果关系母鸡 - 鸡蛋存在,那么矩阵在该位置将有一个 1matrix[0][3],如果不存在,则该值将为 0(您可以选择自己选择的值来决定如何判断关系何时存在或不存在)。如果关系是无向的,那么您只需要矩阵的一侧(例如上三角形)。

+---------------------------------+
| Hen | Cage | Food | Egg | Chick |
+---------------------------------+
|  0  |  1   |  2   |  3  |   4   |
+---------------------------------+

      0   1   2   3   4
    +--------------------+
  0 | 0 | 1 | 0 | 1 | 1  |
    +---+---+---+---+----+
  1 | 0 | 0 | 0 | 1 | 1  |
    +---+---+---+---+----+
  2 | 0 | 0 | 0 | 0 | 1  |
    +---+---+---+---+----+
  3 | 0 | 0 | 0 | 0 | 1  |
    +---+---+---+---+----+
  4 | 0 | 0 | 0 | 0 | 0  |
    +--------------------+

该解决方案的缺点隐藏在内存使用中,特别是当矩阵包含大量 0(不存在的关系)时;您将不必要地占用大量空间。在这种情况下,您可以使用图的链表表示 http://www.geeksforgeeks.org/graph-and-its-representations/.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

存储各种类型对象之间的许多 1:1 关系:解耦和高性能 的相关文章

  • 为什么 strcat() 之后字符串会被改变?

    这是源代码 int main char str dance char str1 hello char str2 abcd strcat str1 str2 printf s str output bcd why str更改后strcat s
  • 如何在 Google 日历中创建“recurData”?

    我想使用 Google API 创建日历的重复事件 我正在关注链接 谷歌日历API http code google com apis calendar data 2 0 developers guide dotnet html Creat
  • 如何在 javascript 中使用 .net 资源文件

    无论如何 我可以在 javascript 中访问我的资源文件 resx 吗 如果没有 那么是否有任何解决方法可以用不同语言的 javascript 显示消息 如果您的 javascript 在页面中 您可以使用 var globalReso
  • lua_resume 的 from 参数的含义

    From Lua 5 2 参考手册 http www lua org manual 5 2 manual html lua resume int lua resume lua State L lua State from int nargs
  • 如果文本框不为空,如何添加并显示工具提示文本框 WPF

    需要显示提示 其中包含文本字段中的数据 文本框有数据时出现提示 只需使用绑定到 ToolTipService 附加属性即可 XAML
  • MDI应用程序中父窗体的问题

    我使用按钮作为容器中的控件 父窗体 当子窗体出现时 父窗体中的控件 按钮 图片 标签 出现在子窗体上并将其覆盖 我看不到子窗体 有谁知道如何防止这种情况 我不想将这些控件设置为 Control Visible false 因为当我最小化子表
  • Task.WaitAll 保持循环

    我正在尝试这个异步代码只是为了测试 async 关键字 public async Task
  • 不明确的元函数或未定义的类型

    我是元功能的新手 我想编写一个函数 将复合类型中某种类型的所有匹配项替换为其他类型 在示例中 replace
  • 为 C# 和 C++ 应用程序编写 DLL

    我需要编写几个 DLL 它们都可以从 C 应用程序和 C 应用程序访问 最初 我认为通过用 C 编写 DLL 并从 C 和 C 应用程序链接到它们可以节省时间 精力 这种方法明智吗 还是应该使用 C 编写 DLL 我的建议是在您最舒服的地方
  • 包含不同类型的两个集合相交

    假设我有一个集合 称之为ids它是类型IEnumerable
  • 使用 ASP.NET Core Identity 将令牌保存在 Cookie 中

    我想在我的 身份 生成的 cookie 中保存一些内容 我目前正在使用文档中的默认身份设置 启动 cs services Configure
  • MVC Razor for 循环

    我有这段代码 嵌套在表单帖子内 但我不断收到错误 它缺少结束语 for int i 0 i lt itemsCount i
  • dev_t 和 ino_t 是否必须是整数类型?

    glibc 的文档保留它们是整数类型 不比 unsigned int 窄 但我没有找到说明它们必须是整数类型的标准参考 另请参阅 time t 所以最后 问题就变成了 include
  • 如何从与桌面交互的应用程序与 Windows 服务进行通信?

    使用 Net 与服务交互的最佳方式是什么 即大多数托盘应用程序如何与其服务器通信 如果这个方法也是跨平台的 那就更好了 在 Mono 中工作 所以我猜远程处理已经过时了 Edit 忘了说了 我们仍然需要在现场支持 Windows 2000
  • 非数字输入导致死循环

    由于某种原因 如果用户输入了错误的数据类型 例如 j 或 循环将停止要求输入并继续显示 Enter an integer gt 一遍又一遍 如何让程序处理错误的输入 为什么输入非数字值会导致如此奇怪的行为 define SENTINEL 0
  • 如何从 .NET DataGridView 控件单元格值写入文本文件?

    我有以下代码应该循环遍历我的所有行DataGridView 并将其所有单元格值写入文本文件 但是 它输出所有行 但仅输出每行的第一个单元格 而不输出其他三个单元格 string file name C test1 txt var objWr
  • 显式调用静态构造函数

    我想为下面的课程编写单元测试 如果名称不是 MyEntity 则 mgr 应为空 消极的单元测试 使用 Manager 私有访问器 我想将名称更改为 Test 以便 mgr 应该为空 然后会验证 mgr 值 为了实现这一点 我想显式调用静态
  • MDI 窗体中的子窗口对接

    我有一个 MDI 表单和其中的一些子表单 我将子窗体停靠到 MDI 窗口的不同区域 但是当任何子窗体失去焦点时 其他停靠的窗体将重新排列 由于混乱 我准备了一组图像来展示该行为 Image1 单击任何窗口之前 Image2 点击窗口2后 问
  • Security.h 中结构的 macOS 文档

    我正在尝试使用Security h通过 Java 和 JNA 的 macOS 框架 这意味着我需要将某些结构重建为 Java 类 问题是 当我查看文档中的结构时 this one https developer apple com refe
  • C++ 模板类问题中的类型条件

    使用海湾合作委员会4 2 我有这个条件类型的元模板 template

随机推荐