C++ 使用额外的变量使计算更容易理解-(我的代码慢了多少)?

C++ 使用额外的变量使计算更容易理解-(我的代码慢了多少)?,c++,runtime,C++,Runtime,主要问题 假设我正在编写一个函数,当两个水滴碰撞时,求出生成的球状体的半径: double drop_size_adder(double r1, double r2) { return cbrt((4 / 3 * M_PI * r1*r1*r1 + 4 / 3 * M_PI * r2*r2*r2) * 3 / (4 * M_PI)); } (我意识到这其中有很多因素是不正确的,但就问题的这一部分而言,想象一下情况并非如此。) 我可以重写上述计算,通过引入各种变量将计算分为几个步骤,使其

主要问题

假设我正在编写一个函数,当两个水滴碰撞时,求出生成的球状体的半径:

double drop_size_adder(double r1, double r2) {
    return cbrt((4 / 3 * M_PI * r1*r1*r1 + 4 / 3 * M_PI * r2*r2*r2) * 3 / (4 * M_PI));
}
(我意识到这其中有很多因素是不正确的,但就问题的这一部分而言,想象一下情况并非如此。)

我可以重写上述计算,通过引入各种变量将计算分为几个步骤,使其更容易理解发生了什么:

double drop_size_adder(double r1, double r2) {
    double vol1, vol2, vol3, r3;
    vol1 = 4 / 3 * M_PI * r1*r1*r1;
    vol2 = 4 / 3 * M_PI * r2*r2*r2;
    vol3 = vol1 + vol2;
    r3 = cbrt(3 * vol3 / (4 * M_PI));
    return r3;
}
这会显著增加函数运行所需的时间吗

次要问题

此外,假设我重写了上述函数,下面两段代码之间是否存在显著的运行时差异:

double drop_size_adder(double r1, double r2) {
    return cbrt(r1*r1*r1 + r2*r2*r2);
}

int main()
{
    double water_r = 3.2;
    double oil_r = 5.4;
    combined_r = drop_size_adder(water_r, oil_r);
}


在调试构建中,在调试器中,该代码将更易于逐步执行并查看发生了什么,是的

在优化构建中,输出应与较少的“可步进”版本相同

您甚至可以使用类似的方法将编译后的输出与各种编译器标志进行比较
-O2
(大写字母“o”,而不是零)是一个通常支持的编译器标志。它还允许您比较不同编译器的输出/行为

如果没有优化标志,程序集将更改。有了它,一切都会一样。这正是你想要的


现在的编译器优化非常好。优化执行速度更多的是关于算法/容器(“大O”)和内存使用模式(“缓存一致性”)的,而不是仅仅调整程序集。

为可读性编写代码。别装聪明

这就是说,如果您仍然想知道差异是什么,那么您可以查看编译器的输出(例如)。这:

由gcc(-O3)翻译为:


我不擅长组装,但显然两者是相同的。结论:如果您确实关心效率,那么仍然要为可读性编写代码。编译器很可能比您更了解如何优化代码。

如果您告诉编译器优化代码,则没有区别。编译器很可能会将第二个代码块转换为第一个代码块。检查总成以确认。如果你真的很担心,你可以使用像google benchmark(你可以用来玩)这样的工具来获取真实的数据,然后你可以自己探索一下,live:这并不能解决这个问题,但是请注意,
4/3
是1。我会写
constepr double drop\u size\u adder(double r1,double r2){return cbrt((sphere\u volume(r1)+sphere_volume(r2))/sphere_volume(1.);}
int main()
{
    double water_r = 3.2;
    double oil_r = 5.4;
    combined_r = cbrt(water_r*water_r*water_r + oil_r*oil_r*oil_r);
}
#define M_PI 1

double cbrt(double);

double drop_size_adder(double r1, double r2) {
    return cbrt((4 / 3 * M_PI * r1*r1*r1 + 4 / 3 * M_PI * r2*r2*r2) * 3 / (4 * M_PI));
}

double drop_size_adder2(double r1, double r2) {
    double vol1, vol2, vol3, r3;
    vol1 = 4 / 3 * M_PI * r1*r1*r1;
    vol2 = 4 / 3 * M_PI * r2*r2*r2;
    vol3 = vol1 + vol2;
    r3 = cbrt(3 * vol3 / (4 * M_PI));
    return r3;
}
_Z15drop_size_adderdd:
        movapd  xmm2, xmm0
        mulsd   xmm0, xmm0
        mulsd   xmm0, xmm2
        movapd  xmm2, xmm1
        mulsd   xmm2, xmm1
        mulsd   xmm2, xmm1
        addsd   xmm0, xmm2
        mulsd   xmm0, QWORD PTR .LC0[rip]
        mulsd   xmm0, QWORD PTR .LC1[rip]
        jmp     _Z4cbrtd
_Z16drop_size_adder2dd:
        movapd  xmm2, xmm0
        mulsd   xmm0, xmm0
        mulsd   xmm0, xmm2
        movapd  xmm2, xmm1
        mulsd   xmm2, xmm1
        mulsd   xmm2, xmm1
        addsd   xmm0, xmm2
        mulsd   xmm0, QWORD PTR .LC0[rip]
        mulsd   xmm0, QWORD PTR .LC1[rip]
        jmp     _Z4cbrtd
.LC0:
        .long   0
        .long   1074266112
.LC1:
        .long   0
        .long   1070596096