将数据添加到实例的最有效方法

发布于 2024-08-24 08:00:21 字数 820 浏览 5 评论 0原文

我有一个类,比如说 Person,它由另一个类/模块管理,比如说 PersonPool。

我的应用程序中有另一个模块,比如说模块 M,它想要以最有效的方式将信息与人关联起来。我考虑了以下替代方案:

  • 将数据成员添加到 Person,该数据成员由应用程序的其他部分访问。优点是它可能是最快的方法。缺点是这是相当具有侵入性的。 Person 不需要知道任何关于这个额外数据的信息,如果我想保护这个数据成员不受其他模块的影响,我需要将其设为私有并使模块 M 成为朋友,这是我不喜欢的。
  • 向 Person 添加一个“通用”属性包,其他模块可以在其中添加其他属性。优点是它不是侵入性的(除了具有属性包之外),并且也很容易通过其他模块添加“属性”。缺点是它比直接从 Person 获取值要慢得多。
  • 在模块M中使用map/hashmap,它将Person(指针,id)映射到我们想要存储的值。就数据分离而言,这看起来是最好的解决方案,但速度又慢得多。
  • 给每个人一个唯一的号码,并确保历史上没有两个人得到相同的号码(我什至不想让这些人重复使用一个号码,因为这样老人的数据可能会与老人的数据混淆)一个新人)。然后外部模块可以简单地使用向量将人的唯一编号映射到特定数据。优点是我们不会用不需要知道的数据(除了他唯一的数字)侵入 Person 类,并且我们有一种快速的方法从向量中专门获取模块 M 的数据。缺点是如果删除和创建很多人,向量可能会变得非常大(因为我们不想重复使用唯一的数字)。

在最后一个替代方案中,可以通过使用稀疏向量来解决问题,但我不知道是否有非常有效的稀疏向量实现(比映射/哈希图更快)。

还有其他方法可以完成此任务吗? 或者是否有一个有效的稀疏向量可以解决最后一个替代方案的内存问题?

I have a class, let's say Person, which is managed by another class/module, let's say PersonPool.

I have another module in my application, let's say module M, that wants to associate information with a person, in the most efficient way. I considered the following alternatives:

  • Add a data member to Person, which is accessed by the other part of the application. Advantage is that it is probably the fastest way. Disadvantage is that this is quite invasive. Person doesn't need to know anything about this extra data, and if I want to shield this data member from other modules, I need to make it private and make module M a friend, which I don't like.
  • Add a 'generic' property bag to Person, in which other modules can add additional properties. Advantage is that it's not invasive (besides having the property bag), and it's easy to add 'properties' by other modules as well. Disadvantage is that it is much slower than simply getting the value directly from Person.
  • Use a map/hashmap in module M, which maps the Person (pointer, id) to the value we want to store. This looks like the best solution in terms of separation of data, but again is much slower.
  • Give each person a unique number and make sure that no two persons ever get the same number during history (I don't even want to have these persons reuse a number, because then data of an old person may be mixed up with the data of a new person). Then the external module can simply use a vector to map the person's unique number to the specific data. Advantage is that we don't invade the Person class with data it doesn't need to know of (except his unique nubmer), and that we have a quick way of getting the data specifically for module M from the vector. Disadvantage is that the vector may become really big if lots of persons are deleted and created (because we don't want to reuse the unique number).

In the last alternative, the problem could be solved by using a sparse vector, but I don't know if there are very efficient implementations of a sparse vector (faster than a map/hashmap).

Are there other ways of getting this done?
Or is there an efficient sparse vector that might solve the memory problem of the last alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久随 2024-08-31 08:00:21

我会用map/hashmap来计时解决方案,如果它表现得足够好的话就使用它。否则,您别无选择,只能将这些属性添加到类中,因为这是最有效的方法。

或者,您可以创建 Person 的子类,基本上将所有接口方法转发到原始类,但添加您想要的所有属性,然后在对 M 的某些调用期间将原始 Person 更改为您自己修改的属性。

这样模块 M 将查看子类及其所需的所有属性,但所有其他模块都会将其视为 Person 类的实例,并且将无法查看您的自定义属性。

I would time the solution with map/hashmap and go with it if it performs good enough. Otherwise you have no choice but add those properties to the class as this is the most efficient way.

Alternatively, you can create a subclass of Person, basically forward all the interface methods to the original class but add all the properties you want and just change original Person to your own modified one during some of the calls to M.

This way module M will see the subclass and all the properties it needs but all other modules would think of it as just an instance of Person class and will not be able to see your custom properties.

梨涡少年 2024-08-31 08:00:21

第一个和第三个是相当常见的技术。第二个是动态编程语言(例如 Python 和 Javascript)如何实现对象的成员数据,因此不要因为它太慢而立即忽略它。第四种与关系数据库的工作原理大致相同。让关系数据库像拍板一样运行是可能的,但很困难。

简而言之,您描述了 4 种广泛使用的技术。排除其中任何一个的唯一方法是提供特定于您的问题的详细信息(所需的性能、人员数量、属性数量、代码中想要执行此操作的模块数量等)以及相应的测量结果。

另一种可能性是模块 M 定义一个继承自 Person 的类,并添加额外的数据成员。这里的原则是,M对人的想法与Person对人的想法不同,所以将M的想法描述为一个类。当然,只有在同一 Person 对象上操作的所有其他模块都通过多态性执行此操作,并且此外可以让 M 负责创建对象(可能通过工厂的依赖注入)时,这才有效。这是一个很大的“如果”。一个更大的问题是,如果除了 M 之外没有其他东西需要对对象执行任何生命周期相关的操作,那么您可以优先使用组合或私有继承而不是公共继承。但如果模块 N 要创建 Person 的集合,然后模块 M 想要向它们附加额外的数据,那么这些都没有任何用处。

The first and third are reasonably common techniques. The second is how dynamic programming languages such as Python and Javascript implement member data for objects, so do not dismiss it out of hand as impossibly slow. The fourth is in the same ballpark as how relational databases work. It is possible, but difficult, to make relational databases run the like the clappers.

In short, you've described 4 widely used techniques. The only way to rule any of them out is with details specific to your problem (required performance, number of Persons, number of properties, number of modules in your code that will want to do this, etc), and corresponding measurements.

Another possibility is for module M to define a class which inherits from Person, and adds extra data members. The principle here is that M's idea of a person differs from Person's idea of a person, so describe M's idea as a class. Of course this only works if all other modules operating on the same Person objects are doing so via polymorphism, and furthermore if M can be made responsible for creating the objects (perhaps via dependency injection of a factory). That's quite a big "if". An even bigger one, if nothing other than M needs to do anything life-cycle-ish with the objects, then you may be able to use composition or private inheritance in preference to public inheritance. But none of it is any use if module N is going to create a collection of Persons, and then module M wants to attach extra data to them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文