2013-06-10 2 views
1

Я слышал много людей говорятПочему одно назначение быстрее, чем другое?

int a = 0; 
a += 10; 

быстрее, чем

int a = 0; 
a = a + 10; 

Почему? Я отлаживал его с помощью gdb, и это были абсолютно одинаковые инструкции.

GDB:

Первый

(gdb) list 
1 int main() 
2 { 
3  int counter = 0; 
4  counter = counter + 10; 
5  return 0; 
6 } 
(gdb) disassemble main 
Dump of assembler code for function main: 
    0x00000000004004cc <+0>: push %rbp 
    0x00000000004004cd <+1>: mov %rsp,%rbp 
    0x00000000004004d0 <+4>: movl $0x0,-0x4(%rbp) 
    0x00000000004004d7 <+11>: addl $0xa,-0x4(%rbp) 
=> 0x00000000004004db <+15>: mov $0x0,%eax 
    0x00000000004004e0 <+20>: pop %rbp 
    0x00000000004004e1 <+21>: retq 
End of assembler dump. 

Второй

(gdb) list 
1 int main() 
2 { 
3  int counter = 0; 
4  counter += 10; 
5  return 0; 
6 } 

(gdb) disassemble main 
Dump of assembler code for function main: 
    0x00000000004004cc <+0>: push %rbp 
    0x00000000004004cd <+1>: mov %rsp,%rbp 
    0x00000000004004d0 <+4>: movl $0x0,-0x4(%rbp) 
    0x00000000004004d7 <+11>: addl $0xa,-0x4(%rbp) 
=> 0x00000000004004db <+15>: mov $0x0,%eax 
    0x00000000004004e0 <+20>: pop %rbp 
    0x00000000004004e1 <+21>: retq 
End of assembler dump. 

Так почему "(переменная) + = (значение)" быстрее, чем «(переменная) = (переменная) + (стоимость)" ?

+15

Какими людьми являются эти люди? – glglgl

+0

Не знаю. Видел много людей на форумах. Даже здесь, в stackoverflow. – Davlog

+0

Я не думаю, что они разные, кроме синтаксически. – vidit

ответ

6

Как говорили другие, в данном случае это не имеет значения. Тем не менее, есть некоторые похожие, но очень разные случаи:

int *f(void); 
(*f()) = (*f()) + 1; 
(*f()) += 1; 

В 2-й линии, f() вызывается дважды, в 3-й строке только один раз.

int * volatile *p; 
**p = **p + 1; 
**p += 2; 

Во 2-й линии, компилятор будет читать *p дважды, предполагая, что это может измениться между доступов (и вы бы читать одно место, писать другой). В 3-м он будет читать *p один раз и увеличивать это место.

И если вы чувствуете себя непослушным:

#define a *f() 
int a; 
a = a + 1; 
a++; 

выглядит почти так же, как и в вопросе, но ведет себя, как мой первый пример.

8

Это не быстрее. Как видите, сгенерированная сборка идентична. Тот, кто вам сказал, быстрее рассказывал истории.

+1

Не совсем. Вероятно, это связано с тем, что в C++ первый * может быть быстрее, поскольку он не создает временную. Тот, кто сказал это OP, вероятно, смешивал C и C++. –

+3

Даже в C++ любой современный компилятор собирается «поступить правильно». Несмотря на это, вопрос помечен C, OP продемонстрировал, что они идентичны, и это примерно в конце этого ... –

+1

Да, я просто предоставлял разумное объяснение по поводу вопроса OP ... –

3

Я думаю, вы только что доказали, что это не быстрее для любого компилятора c, который вы используете. Тем не менее, во время компиляции у вас могут быть оптимизации. Кроме того, другие компиляторы могут не делать то же самое.

0

У вас неверная информация. Обе инструкции заняты в одно и то же время.

Оба

int a = 0; 
a += 10; 

и

int a = 0; 
a = a + 10; 

генерирует один и тот же код сборки и имеющие одинаковую скорость.

2

Я думаю, что они означают «быстрее», так это то, что его легче набрать , чем a = a + 10. Оба они полностью идентичны.

1

Вы должны посмотреть на это на компиляторе по базе компилятора и по опции. Неоптимизированный он может генерировать другой код, но в то же время неоптимизированный, вероятно, будет намного медленнее даже для этой одной строки кода. Реальный ответ связан с внутренними компонентами компилятора, которые вы можете увидеть очень легко с clang/llvm, но, возможно, с gcc и другими. К тому моменту, когда он генерирует сборку, он идет по дороге, у компиляторов, как правило, есть внутренний общий код, который получает некоторую оптимизацию, тогда окончательное преобразование в код сборки/машины имеет дополнительную целевую специфическую оптимизацию. Интересный ответ на ваш вопрос - что делает интерфейс компилятора с этими двумя тонкими разными строками кода? Если не с самого начала, в какой момент эти два соединения соединяются и становятся тем же результатом на выходе или сбое сборки/машинного кода?

+2

Хотя я верю в принципе, мне трудно представить, каким образом они могут отличаться. – ugoren

+0

Согласовано .... , , –

Смежные вопросы