假设数字的值非常大,例如9,046,744,073,709,551,615。
我使用加法,乘法和左移将值翻倍。
#include <iostream>
using namespace std;
int main(){
unsigned long long int value = 9046744073709551615;
cout << (value + value) << endl;
cout << (value * 2) << endl;
cout << (value << 1) << endl;
return 0;
}
哪个计算会更快?
答案 0 :(得分:1)
简短的答案是,没有其他选择更快。启用编译器优化后,它们会产生相同的代码。
对于在编译时知道该值的情况,程序集是这样的:Compiler Explorer link
movabs rsi, -353255926290448386
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long long>(unsigned long long)
它将常量加载到寄存器中并调用operator<<()
。所有这三种选择都会产生这种优化的装配。
对于在运行时读取值的情况,程序集是这样的:Compiler Explorer link
mov rax, QWORD PTR [rsp+8]
mov edi, OFFSET FLAT:_ZSt4cout
lea rsi, [rax+rax]
call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long long>(unsigned long long)
它使用加法(rax+rax
)并调用operator<<()
。同样,所有这三种选择都产生相同的装配。
答案 1 :(得分:0)
我刚刚从godbolt中选择了一个编译器。确实,完全没有区别。尝试编译器和优化级别。
在-O0
中使用x86-64_gcc的结果是以下结果的三倍:
mov rax, QWORD PTR [rbp-8]
add rax, rax
mov rsi, rax
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned long long)
mov esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))