假设我在抽象基类指针 mypointer->foo() 上有一个虚函数调用 foo()。当我的应用程序启动时,根据文件的内容,它选择实例化一个特定的具体类并将 mypointer 分配给该实例。在应用程序的余生中,mypointer 将始终指向该具体类型的对象。我无法知道这个具体类型是什么(它可能由动态加载库中的工厂实例化)。我只知道在第一次创建具体类型的实例后类型将保持不变。指针可能并不总是指向同一个对象,但该对象总是具有相同的具体类型。请注意,类型在技术上是在“运行时”确定的,因为它基于文件的内容,但在“启动”(加载文件)之后,类型是固定的。
但是,在 C++ 中,每次在应用程序的整个持续时间内调用 foo 时,我都会支付虚函数查找成本。编译器无法优化查找,因为它无法知道具体类型在运行时不会发生变化(即使它是有史以来最神奇的编译器,它也无法推测动态加载的行为图书馆)。在 Java 或 .NET 等 JIT 编译语言中,JIT 可以检测到重复使用相同的类型并进行内联缓存。我基本上是在寻找一种方法来手动为 C++ 中的特定指针执行此操作。
C++ 中有什么方法可以缓存这个查找吗?我意识到解决方案可能非常骇人听闻。如果可以编写配置测试来发现 ABI/编译器的相关方面,那么我愿意接受 ABI/编译器特定的 hack,即使它不是真正可移植的,它也是“实际上可移植的”。
更新:对于反对者:如果这不值得优化,那么我怀疑现代 JIT 会这样做。您是否认为 Sun 和 MS 的工程师正在浪费时间实施内联缓存,并且没有对其进行基准测试以确保有改进?