C 在if-else的每种情况下,返回的速度会更快/使用更少的内存吗?

C 在if-else的每种情况下,返回的速度会更快/使用更少的内存吗?,c,performance,memory,C,Performance,Memory,最近,我在CS研究中得到了一个代码示例(参见代码#1),我试图得出我的第二个版本的代码是更快还是使用更少的内存。 你对我的问题有答案吗 // Code #1 double f(double b, double x) { double s; if (x == 0.0) s = 1.0; else s = sin(x)/x; return s + b; } // Code #2 double f(double b, double x)

最近,我在CS研究中得到了一个代码示例(参见代码#1),我试图得出我的第二个版本的代码是更快还是使用更少的内存。 你对我的问题有答案吗

// Code #1
double f(double b, double x)
{
    double s;
    if (x == 0.0)
        s = 1.0;
    else
        s = sin(x)/x;
    return s + b;
}

// Code #2
double f(double b, double x)
{
    // I thought this would be faster and using less memory due to 
    // not declaring a new double
    if (x == 0.0)
        return 1.0 + b;
    else
        return sin(x)/x + b;
}

谢谢你们的帮助。

这取决于编译器和优化标志。通常,这两个代码将给出相同的结果。

这取决于编译器和优化标志。一般来说,这两种代码将给出相同的结果。

我已经生成了这两种情况的汇编

案例1:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        movsd   QWORD PTR [rbp-24], xmm0
        movsd   QWORD PTR [rbp-32], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jne     .L2
        movsd   xmm0, QWORD PTR .LC1[rip]
        movsd   QWORD PTR [rbp-8], xmm0
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-32]
        mov     QWORD PTR [rbp-40], rax
        movsd   xmm0, QWORD PTR [rbp-40]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-32]
        movsd   QWORD PTR [rbp-8], xmm0
.L4:
        movsd   xmm0, QWORD PTR [rbp-8]
        addsd   xmm0, QWORD PTR [rbp-24]
        leave
        ret
.LC1:
        .long   0
        .long   1072693248
案例2:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        movsd   QWORD PTR [rbp-8], xmm0
        movsd   QWORD PTR [rbp-16], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jne     .L2
        movsd   xmm1, QWORD PTR [rbp-8]
        movsd   xmm0, QWORD PTR .LC1[rip]
        addsd   xmm0, xmm1
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-16]
        mov     QWORD PTR [rbp-24], rax
        movsd   xmm0, QWORD PTR [rbp-24]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-16]
        addsd   xmm0, QWORD PTR [rbp-8]
.L4:
        leave
        ret
.LC1:
        .long   0
        .long   1072693248

没有区别。所以,它们之间没有速度优化。所以,代码优化取决于编译器。

我已经生成了这两种情况的汇编

案例1:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        movsd   QWORD PTR [rbp-24], xmm0
        movsd   QWORD PTR [rbp-32], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jne     .L2
        movsd   xmm0, QWORD PTR .LC1[rip]
        movsd   QWORD PTR [rbp-8], xmm0
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-32]
        mov     QWORD PTR [rbp-40], rax
        movsd   xmm0, QWORD PTR [rbp-40]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-32]
        movsd   QWORD PTR [rbp-8], xmm0
.L4:
        movsd   xmm0, QWORD PTR [rbp-8]
        addsd   xmm0, QWORD PTR [rbp-24]
        leave
        ret
.LC1:
        .long   0
        .long   1072693248
案例2:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        movsd   QWORD PTR [rbp-8], xmm0
        movsd   QWORD PTR [rbp-16], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jne     .L2
        movsd   xmm1, QWORD PTR [rbp-8]
        movsd   xmm0, QWORD PTR .LC1[rip]
        addsd   xmm0, xmm1
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-16]
        mov     QWORD PTR [rbp-24], rax
        movsd   xmm0, QWORD PTR [rbp-24]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-16]
        addsd   xmm0, QWORD PTR [rbp-8]
.L4:
        leave
        ret
.LC1:
        .long   0
        .long   1072693248

没有区别。所以,它们之间没有速度优化。所以,代码优化依赖于编译器。

只声明变量并不是唯一占用内存的事情

int a = 1 + 2;
int b = 3;
int c = a + b;
此代码将采用与以下代码相同的值

int c = 1 + 2 + 3;
因为最终处理器将在单核中一次执行一个操作。

第二个代码添加两个数字并将其保存在堆栈中,然后将第三个数字添加到前两个数字的结果中。

仅声明变量并不是唯一占用内存的事情

int a = 1 + 2;
int b = 3;
int c = a + b;
此代码将采用与以下代码相同的值

int c = 1 + 2 + 3;
因为最终处理器将在单核中一次执行一个操作。

第二个代码添加两个数字并将其保存在堆栈中,然后将第三个数字添加到前两个数字的结果中。

简短回答:不用担心

长答覆:

sin
在这个函数中花费的时间最多,因此如果有一些额外的指令,也不会有任何明显的效果

尽管有疑问,在生成的代码

对于x86_64上的GCC 6.3,第一个版本使用了1个寄存器(xmm2),但优化器能够更好地对指令重新排序

第1版:

        ucomisd xmm1, QWORD PTR .LC1[rip]
        movapd  xmm2, xmm0
        jp      .L5
        movsd   xmm0, QWORD PTR .LC0[rip]
        je      .L7
.L5:
        movapd  xmm0, xmm1
        sub     rsp, 24
        movsd   QWORD PTR [rsp+8], xmm2
        movsd   QWORD PTR [rsp], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp]
        movsd   xmm2, QWORD PTR [rsp+8]
        add     rsp, 24
        divsd   xmm0, xmm1
        addsd   xmm0, xmm2
        ret
.L7:
        addsd   xmm0, xmm2
        ret
第2版:

        ucomisd xmm1, QWORD PTR .LC0[rip]
        jp      .L2
        je      .L10
.L2:
        sub     rsp, 24
        movsd   QWORD PTR [rsp], xmm0
        movapd  xmm0, xmm1
        movsd   QWORD PTR [rsp+8], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp+8]
        divsd   xmm0, xmm1
        addsd   xmm0, QWORD PTR [rsp]
        add     rsp, 24
        ret
.L10:
        addsd   xmm0, QWORD PTR .LC1[rip]
        ret

那么这两个版本在性能上有多大差异呢?只有性能测试才能确定(但我猜你不会看到任何区别)。

简短回答:别担心

长答覆:

sin
在这个函数中花费的时间最多,因此如果有一些额外的指令,也不会有任何明显的效果

尽管有疑问,在生成的代码

对于x86_64上的GCC 6.3,第一个版本使用了1个寄存器(xmm2),但优化器能够更好地对指令重新排序

第1版:

        ucomisd xmm1, QWORD PTR .LC1[rip]
        movapd  xmm2, xmm0
        jp      .L5
        movsd   xmm0, QWORD PTR .LC0[rip]
        je      .L7
.L5:
        movapd  xmm0, xmm1
        sub     rsp, 24
        movsd   QWORD PTR [rsp+8], xmm2
        movsd   QWORD PTR [rsp], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp]
        movsd   xmm2, QWORD PTR [rsp+8]
        add     rsp, 24
        divsd   xmm0, xmm1
        addsd   xmm0, xmm2
        ret
.L7:
        addsd   xmm0, xmm2
        ret
第2版:

        ucomisd xmm1, QWORD PTR .LC0[rip]
        jp      .L2
        je      .L10
.L2:
        sub     rsp, 24
        movsd   QWORD PTR [rsp], xmm0
        movapd  xmm0, xmm1
        movsd   QWORD PTR [rsp+8], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp+8]
        divsd   xmm0, xmm1
        addsd   xmm0, QWORD PTR [rsp]
        add     rsp, 24
        ret
.L10:
        addsd   xmm0, QWORD PTR .LC1[rip]
        ret

那么这两个版本在性能上有多大差异呢?只有性能测试才能确定(但我猜你不会看到任何区别)。

c++不是c,请只选择一个标记,这样你就可以得到你需要的答案除非你使用的编译器是****,否则它们可能会被优化到相同的代码。你总是可以自己拆开看看。理论上第二种可能会更快,只是在实践中可能不会。没有区别。编译器可以很容易地进行这样的转换。无论如何,
sin(x)
将花费最多的时间。@George-几乎相同的代码()@HB-这在代码审查中是离题的。不要随便地建议它。C++不是C,请只选择一个标签,这样你就可以得到你需要的答案,除非你使用的编译器是***,否则它们可能会被优化到相同的代码。你总是可以自己拆开看看。理论上第二种可能会更快,只是在实践中可能不会。没有区别。编译器可以很容易地进行这样的转换。无论如何,
sin(x)
将花费最多的时间。@George-几乎相同的代码()@HB-这在代码审查中是离题的。不要胡说。那是什么?
.LC1[rip]
?它会做什么?那是什么?它能做什么?