【问题标题】:Techniques implement polymorphism but save on the 4 bytes技术实现了多态性,但节省了 4 个字节
【发布时间】:2011-07-30 06:21:53
【问题描述】:

我在模板元数据编程中遇到了一种技术,它允许在没有虚函数机制的情况下实现多态性。

因此我想知道是否还有其他一些技巧可以用来在 c++ 或 C# 中进行多态行为?

编辑:前一段时间我读到访问者设计模式是虚拟机制的替代方案,但不记得这篇文章。有人可以确认它也可以使用吗?

EDIT2:我知道这不是一种理想的编程实践,但我正在寻找 hack,因为优化是首要关注点。类层次结构在编译时分配(指针在运行时不通过 if-else 逻辑等分配给类)

【问题讨论】:

  • 为什么需要节省 4 个字节?除非你在手表或其他东西上运行它,否则真的没关系......
  • 我想把对象放在一个大数组中..
  • @tjameson,甚至 watches 现在都在运行 Java :)
  • 多大? 4个字节不算什么。例如,如果您有 1,000,000 个条目,则小于 4 MB。你会遇到比节省几兆字节更大的问题......
  • 对象有多大?它们真的只包含一个 4 字节的 vtable 吗?

标签: c# c++ optimization


【解决方案1】:

你有没有想过为什么多态每次使用都会增加大约 4 字节的开销?这是因为这是实现多态性的最简单、最实用的方法。可能有一些怪诞的 hack 可以用更少的开销来模拟 C++/C#/Objective-C 多态性,但它们带来了很大的权衡——例如,每次调用的 CPU 使用量是 CPU 使用率的几倍,或者扩展性有限的静态存储类层次结构。

多态是按照它的实现方式实现的,因为它的实现方式已经是最优的了。

【讨论】:

  • 他总是可以为他的数据使用一个结构体,并通过指向实际数据的指针实现多态性......
  • 嗯,他说他想优化掉多态的 4 个字节,而不是指针。哈哈。无论如何,这会将内存从数组中取出并将其放在其他地方(尽管他每次想要访问他的数据时都必须创建一个新对象,但不会再有 4 个字节 =D)。
【解决方案2】:

(编辑:这是 C# 上下文中的答案。)

无论如何,每个对象都不会保存 4 个字节。该类型仍然有一个 vtable 来查找函数成员实现。您可以通过避免使用虚拟方法在该表中保存一个条目,但这是单个对象中的单个条目 - 它不会影响每个实例。

要么你错过了什么,要么我错过了。如果您可以编辑问题以显示您在最自然实施中尝试做什么,这将有所帮助 - 然后说明您要节省空间的地方。

【讨论】:

  • @Jerry: 而在 C# 中,每个引用类型对象都有一个对其实际类型的引用,无论有多少虚拟方法......
【解决方案3】:

模板只能用于实现编译时多态性。我不知道有什么机制可以在没有空间开销的情况下实现运行时多态性,但为什么重要呢?如果你需要运行时多态来解决你的问题,你应该使用它。

【讨论】:

    【解决方案4】:

    如果你真的想节省内存,你可以实现你自己的内存处理。块页眉和页脚每个都大于 4 个字节(我认为它们每个是 8 个字节),因此将所有内容放在一个巨大的内存块中并进行自己的索引将是可行的方法。甚至不使用对象,只使用二进制索引。

    我的意思是,除非您正在设计低级数据库、操作系统内核或SOC,否则您真的不应该担心这一点。尤其是 C#。你知道垃圾回收有多少开销吗?

    【讨论】:

      【解决方案5】:

      有很多技巧,从众所周知的技术(例如,C++ 中的 CRTP)到相当丑陋的 hack(我曾经通过消除 vtable 指针将特定程序的容量大致提高了五倍;相反,我为每个类,并根据对象的地址找到正确的 vtable)。

      访问者模式实际上只是取代多态而不是替换它。换句话说,被访问的类中可能/本来应该是多态行为的东西被移到了访问者类中。然而,为了获得动态绑定,您仍然有访问者类的层次结构,通常使用通常的 vtable 机制来实现多态性。在适当的情况下,这仍然可以节省相当多的内存,因为访问者对象的数量通常远小于他们访问的对象数量。

      【讨论】:

      • 在 RAM 有限的嵌入式编程项目中找到了 C++/CRTP(如 Alexandrescu 所述)的良好用例。我不得不同意通过 OO 实现的多态性更自然——导致代码更简洁。
      【解决方案6】:

      Boost.Variant 是访问者设计模式的 C++ 库实现,可避免动态多态性。

      为了您的启迪,您提到的 C++ 静态多态方法有一个名称:CRTP

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-30
        • 2014-10-31
        • 2012-12-23
        • 1970-01-01
        • 1970-01-01
        • 2012-10-07
        • 1970-01-01
        相关资源
        最近更新 更多