我们应该为函数的返回值使用临时变量吗?

tot*_*dli 10 c++ performance

我想到了这一点:这两种做法是否有性能差异:

  1. 将函数的返回值存储在临时变量中,而不是将该变量作为参数提供给另一个函数.
  2. 将该功能放入另一个功能.

规格

假设所有类和函数都正确编写.

情况1.

ClassA a = function1();
ClassB b = function2(a);
function3(b);
Run Code Online (Sandbox Code Playgroud)

案例2.

function3(function2(function1()));
Run Code Online (Sandbox Code Playgroud)

我知道只有一次运行没有太大区别,但我认为我们可以在循环中运行很多次,我创建了一些测试.

测试

#include <iostream>
#include <ctime>
#include <math.h>
using namespace std;

int main()
{
   clock_t start = clock();
   clock_t ends = clock();

   // Case 1.
   start = clock();
   for (int i=0; i<10000000; i++)
   {
      double a = cos(1);
      double b = pow(a, 2);
      sqrt(b);
   }
   ends = clock();
   cout << (double) (ends - start) / CLOCKS_PER_SEC << endl;

   // Case 2.
   start = clock();
   for (int i=0; i<10000000; i++)
      sqrt(pow(cos(1),2));
   ends = clock();
   cout << (double) (ends - start) / CLOCKS_PER_SEC << endl;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果

  • 案例1 = 6.375
  • 案例2 = 0.031

为什么第一个更慢,如果第二个更快,为什么我们不总是这样编写代码?无论如何,第二个pratice有一个名字吗?
我还想知道如果我在第一种情况下在for循环之外创建变量会发生什么,但结果是相同的.为什么?

Who*_*aig 4

如果您希望计算紧缩并且您的数字变得更加一致,请打破“抛弃一切”的优化。确保获得正确值的代码实际运行而不是完全被丢弃,我已将两个测试中的结果分配给易失性本地(这并不完全正确使用易失性,但在确保仅价值创造是重要的增量)。

#include <iostream>
#include <ctime>
#include <cmath>
using namespace std;

int main()
{
    clock_t start;
    volatile double val;

    for (int j=1;j<=10;j++)
    {
        // Case 1.
        start = clock();
        for (int i=0; i<2000000; i++)
        {
            double a = cos(1);
            double b = pow(a, 2);
            val = sqrt(b);
        }
        cout << j << ':' << (double) (clock() - start) / CLOCKS_PER_SEC << endl;

        // Case 2.
        start = clock();
        for (int i=0; i<2000000; i++)
            val = sqrt(pow(cos(1),2));
        cout << j << ':' << (double) (clock() - start) / CLOCKS_PER_SEC << endl << endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的 Macbook Air 上生成以下发布编译的输出(无论如何都不是速度恶魔):

1:0.001465
1:0.001305

2:0.001292
2:0.001424

3:0.001297
3:0.001351

4:0.001366
4:0.001342

5:0.001196
5:0.001376

6:0.001341
6:0.001303

7:0.001396
7:0.001422

8:0.001429
8:0.001427

9:0.001408
9:0.001398

10:0.001317
10:0.001353
Run Code Online (Sandbox Code Playgroud)

  • @totymedli 并非如此,人们很容易认为第一个的清晰度比第二个更能吸引开发人员的注意,并且由于优化器无论如何都会抛出“a”和“b”(在这种情况下),最终结果是相同的。对于重要的价值类型来说,每个方法/是否是好的实践或坏的实践是一个对 RVO(返回值优化)有更好理解的人可能比我能更好地回答的问题。对于这种特殊情况,可能会生成相同或接近相同的代码。 (2认同)