变量而不是类调用

时间:2011-10-11 17:33:43

标签: c++ optimization

我最近了解到,如果你有一个类作为函数参数的引用,那么将某些必需的信息存储为局部变量而不是每次需要时访问类成员都是更好的实践和更有效的方法。功能。

所以...

void function(const Sphere& s)
{
    //lots of calls to s.centre and s.radius
}

void function(const Sphere& s)
{
    Vector3 centre = s.centre; float radius = s.radius;
    //an equal amount of calls to centre and radius
}

我被告知第二个更好,但为什么?而且,哪里是一个开始更充分地研究这个问题的好地方? (请给dummys!)

6 个答案:

答案 0 :(得分:9)

无论谁告诉你,这可能都认为第二版可能会更快。

我认为这是一个糟糕的建议,原因有两个:

  1. 实际上可能会或可能不会更快。这取决于编译器,代码究竟在做什么等等。
  2. 即使速度更快,也会尖叫premature optimization。只有在分析代码并确定代码的哪一部分是整体瓶颈之后,才应进行微优化。

答案 1 :(得分:8)

这个概念很直观,但错了。概念是访问成员比局部变量需要更多的计算,因此通过将成员转换为变量,可以节省性能。

但这是错误的。您的编译器将以您无法想象的方式优化它。不要试图比编译器更聪明。

答案 2 :(得分:6)

这可能会非常危险。如果s.centres.radius在执行此函数期间发生更改(比如由于您调用的函数或其他线程),您将在本地变量中找到两个不一致的旧值 - 导致错误。即使您正在安全地执行此操作,为什么在您可以自己回访规范变量时也有机会引入错误?

答案 3 :(得分:5)

你被骗了。此外,除非您对代码进行了分析并发现是代码中效率低下的主要来源,否则您不应该担心此类细节。不要试图超越编译器的优化器。优化代码比使用它更好。

答案 4 :(得分:2)

以下是您的代码的一般展望:

void function(Sphere s)
{
    Vector3 centre = s.centre; float radius = s.radius;
    //an equal amount of calls to centre and radius
}

首先,通过将Sphere作为const引用传递,您可以获得更高的效率。这样,就不会创建新的副本,这可能比成员访问更昂贵。所以要走的路是:

void function(const Sphere& s)
{
    Vector3 centre = s.centre; float radius = s.radius;
    //an equal amount of calls to centre and radius
}

其次,您不应直接访问类的成员。现在可能很容易,但在大型项目中,调试真的很难。您应该使用内联getter和setter。这样,生成的代码是相同的,但您只有一个入口点。

第三,此版本不是线程安全的。如果另一个主题更改s怎么办? s.centers.radius会发生变化,但您仍然会对旧值进行操作。

最后,编译器在优化方面做得比你做得更好,所以最好把这个放到编译器上。

答案 5 :(得分:0)

谁告诉你这是错的。您可以使用内联函数来提高性能。同样在您的示例中使用

void function(Sphere &s) 

使用复制构造函数保存。