gpt4 book ai didi

c++ - 在一个类中内联

转载 作者:行者123 更新时间:2023-11-28 06:25:05 26 4
gpt4 key购买 nike

我有一个模板类,其中大多数方法都在类内部定义,因此可以内联它们。在下面的示例中,我展示了一个复制构造函数,但它可以是任何东西。

template <typename T>
class Vector {
private:
...
public:
Vector(const Vector& v) {
if (condition) {
call_1(...);
} else {
call_2(...);
}
}
};

在此构造函数中,condition 几乎始终为真,因此我想为编译器提供所有提示,以便它内联 call_1 而不是 call_2(我想防止代码膨胀)。我有两个问题:

  1. 起初,我想将call_1call_2定义为对象的方法,并在类和中定义call_1 call_2 类外。我还能做些什么来帮助编译器吗?
  2. 如果我想让许多不同的类共享 call_1call_2 并因此将它们定义为类外的函数,我该怎么办?

谢谢。

最佳答案

所以这有一些不同的方面。

  1. 一般来说代码膨胀 - 不经常执行的代码不应作为内联代码添加到定期执行的一般代码路径中。
  2. 让编译器知道某些路径比其他路径更有可能。

让我们先看一下一般代码膨胀的细节。它会导致更大的可执行文件,这通常不是一件好事。但是性能开销相对较小——如果 vector<T>.push_back 的每个实例,整个可执行文件的大小就不必要地大了。包含相同的大量代码(在大型应用程序中,push_back 可能被调用数千次 [我的 11k 行编译器有大约 70 次调用,它甚至没有太多地使用 vector ],并添加了几十个指令当然会导致整个应用程序明显变大。因此,不内联代码绝对是有值(value)的。

第二个方面对于编译器“做出正确决定”的能力很重要。简单地在类之外声明一个函数可能会有帮助,但除非编译器也知道它不太可能发生,否则不能保证编译器不会内联反射(reflect)异常情况的函数。

但是,在技术方面,唯一可移植的选择是将函数移出类定义。这是至少向编译器提示它不适合内联的唯一方法。但是编译器有时会决定“无论如何都值得内联这段代码”,而且它是模板代码,你不能真的做“让我们把代码放在一个不与调用者一起编译的源文件中”的老把戏。

使用扩展为 __builtin_expect(expr, likely) 的宏其中 expr是你的情况,likely “共同结果”( 0 对于 false1 对于 true )。不幸的是,这在 Microsoft 编译器中不可用。您可能还想探索扩展为“不内联”的宏选项,例如GCC 的 __attribute__((noinline))强制代码不被内联。

使用大多数高级编译器中可用的配置文件驱动优化和相关注释,这将使编译器选择正确的选项。

对于问题 2,一般很难做到这一点 - 编写一些通用代码可能会奏效,例如:

template<T>
T* grow_allocation(T* existing, size_t cur_size, size_t new_size)
{
T* new_alloc = new T[new_size];
// There is probably clever stuff like std::copy and std::move
// that is "better" than this - writing basic loops to clearly
// show what is being done.
for(size_t i = 0; i < cur_size; i++)
{
new_alloc[i] = existing[i];
}
for(size_t i = cur_size; i < new_size; i++)
{
new_alloc[i] = T();
}
// Probably need to deal with "new_size < cur_size" and destroy
// those too...
}

现在您可以从所有具有动态分配的内存区域来保存类型为 T 的对象的地方调用此函数。 . [这是微不足道的构造]

关于c++ - 在一个类中内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28662724/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com