如果我有这段代码:
class MyClass;
class Child
{
public:
void ExecuteChild()
{
parent->ExecuteParent(); //This function
}
MyClass* parent;
};
class MyClass
{
public:
MyClass
{
child = newChild();
chilt->parent = this;
}
void ExecuteParent()
{
//does something
}
Child* child
};
std::vector<MyClass*> objects;
int num = GetRandomNumberBetween5and10();
for(int i = 0; i < num; i++)
{
objects.push_back(new MyClass());
}
for(int i = 0; i < num; i++)
{
objects[i]->Execute());
}
在启用了所有优化的现代C ++编译器下,是否有可能将Child :: ExecuteParent()内联?我问这个,因为我在项目中有非常类似的情况现场,我必须知道继续这个设计是否有任何意义。
答案 0 :(得分:1)
原样,代码无法编译!调用parent->ExecuteParent()
时,未定义MyClass
。也就是说,如果声明和定义的顺序被整理出来并且函数被适当地定义为inline
,则编译器可以内联它们:方法ExecuteParent()
和{{1在编译时已知它们不是ExecuteChild()
。编译器是否内联函数是另一回事。
答案 1 :(得分:1)
我原则上假设方法调用可以内联,因为编译器确实知道objects[i]
的类。
如果真的这样做,我会感到惊讶。
当你拥有所谓的“非常高性能密集点”时,我开始得到一个过早优化的气息,我将其定义为解决性能问题,然后才能确定是否之一。
关于性能问题的关键在于它们是什么让你不知道它们在哪里。 他们在你不知情的情况下存放在你的代码中。 有时,尝试解决想象中的性能问题会导致创建性能问题。 更重要的是,从来没有一个(根据我的经验)。
例如,假设您有三个性能问题:
那你的策略是什么?
如果你过早地修复了B,那么你将节省25%,相比没有修复它可以获得1.33倍的速度提升。 你可能会对此感到满意,但是......
如果你遵循我推荐的诊断过程,那并不意味着不修复B. 这意味着首先让指出A的诊断让你感到惊讶。 如果你先修复它,你可以节省50%,这样可以获得2倍的速度增益。
更重要的是,当你再次进行诊断时,它说现在B占50%的时间,而不是25%,所以它不仅告诉你你是对的,修复它会给你另外2倍的速度增益,而不仅仅是1.33倍。因此在修复A和B之后,你的速度提高了4倍。 (当然,如果先修复B然后修复A,你最终会在同一个地方。)
最后,无论你是否猜到C是一个问题而不是一个非常大的问题,现在它是一个很大的问题,因为你已经修复了A和B.现在C需要50%的时间,而不是12.5%,所以修复它会给你另一个 2倍的加速。 所以现在你的速度比开始时快8倍。
这完全是您用于查找您没有预料到的问题的方法的结果。 这些都是钱。 Here's an example of a 730x speedup,通过修复六个问题的连续性,其中一些问题在开始时非常小,但是在一起时,它们累计超过99.8%的时间。
当然,你可以从中吸取教训,避免陷阱并编写更快的代码,我想你可以称之为过早优化:)