哪个更快,乘法或减法?

Jam*_*mie 5 c optimization performance

我目前正在做一个大学项目,该项目在很大程度上取决于我的解决方案的速度和效率.我对代码所做的微小改动会产生巨大的影响,因为我写的特定功能被称为成千上万次.

我现在已经编写了我项目的主要功能,目前我正在优化我可能做的所有事情.我正在质疑的代码的一个特定部分如下所示:

array[i] *= -1;
Run Code Online (Sandbox Code Playgroud)

我考虑优化到:

array[i] = 0 - array[i];
Run Code Online (Sandbox Code Playgroud)

改变这段代码会不会影响速度?减法运算比乘法运算更快吗?或者这种问题是过去的事情?

Nik*_* C. 18

忽略了你应该使用它的事实:

array[i] = -array[i];
Run Code Online (Sandbox Code Playgroud)

因为它直接表明意图,所以IMO更清晰,让我们检查编译器对该程序的作用(x86-64上的GCC 4.7.2):

#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t t = time(NULL);
    t *= -1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc -S mult.c -o 1.s

为此:

#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t t = time(NULL);
    t = 0 - t;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc -S sub.c -o 2.s

现在比较两个汇编输出:

diff 1.s 2.s

什么都没打印.编译器为两个版本生成了相同的确切代码.所以答案是:你使用什么并不重要.编译器会选择最快的.这是一个非常容易的优化(如果你甚至可以称之为优化),所以我们可以假设几乎每个编译器都会选择最快的方式为给定的CPU架构做这件事.

作为参考,生成的代码是:

int main()
{
    time_t t = time(NULL);
       mov    edi,0x0
       call   12 
       mov    QWORD PTR [rbp-0x8],rax

    t *= -1;
       neg    QWORD PTR [rbp-0x8]

    t = 0 - t;
       neg    QWORD PTR [rbp-0x8]

    return 0;
       mov    eax,0x0
}

在这两种情况下,它都使用NEG来否定价值.t *= -1t = 0 - t产生:

neg QWORD PTR [rbp-0x8]


har*_*ald 13

只有一种理智的方式来进行优化,那就是测量应用程序的性能.一个好的剖析器可以告诉你很多,但只是计划程序的执行时间和各种修改也可以提供很大的帮助.我会首先使用探查器,但要找到瓶颈所在.

至于你的具体问题,正如其他人所指出的那样,这将是高度依赖于架构的.


Ola*_*che 5

编译器足够聪明,可以将其转换为高效的操作.例如

C源

void f()
{
    int a = 7, b = 7;
    a *= -1;
    b = -b;
}
Run Code Online (Sandbox Code Playgroud)

给予使用 gcc -S a.c

    .file    "a.c"
    .text
    .globl    f
    .type    f, @function
f:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $7, -8(%rbp) ; assign 7
    movl    $7, -4(%rbp) ; assign 7
    negl    -8(%rbp)     ; negate variable
    negl    -4(%rbp)     ; negate variable
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    f, .-f
    .ident    "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

这是在使用Ubuntu 12.04和gcc 4.6.3的PC上.您的架构可能会有所不同.