分配 - 找到最多两个没有if
且效率最高的数字。 (我的导师说if
会破坏效率并使程序变慢。)
所以我这样做了:
long num1=555527778658567767676735; // Random Number
long num2=34277745575656835; // Another Random Number
long big; // The Biggest Number
// I KNOW THIS IS NOT SOLVING THE PROBLEM
big = (num1 - num2) - (num1 > num2) * (num1 - num2); // The Code That Is Faster - 2.791 seconds for 10B Times
big = num1 - (num2 > num1) * (num1 - num2); // The Slower Line Of Code - 3.069 second for 10B Times
我的问题是为什么 - big = (num1 - num2) - (num1 > num2) * (num1 - num2);
比这更快 - big = num1 - (num2 > num1) * (num1 - num2);
在第二行中,我不会减去(num1 - num2)
,而是仅执行此操作num1
;如果不计算另一个“事物”,它不应该更快吗?
答案 0 :(得分:3)
这是我的猜测:
编译器简化了表达式:
(num1 - num2) - (num1 > num2) * (num1 - num2)
(1 - (num1 > num2)) * (num1 - num2)
最后
(num1 <= num2) * (num1 - num2)
哪个确实比
更快num1 - (num2 > num1) * (num1 - num2)
感谢@SirGuy,这是来自clang的程序集:
max2(long, long): # @max2(long, long)
xor eax, eax
sub rdi, rsi
cmovg rax, rdi
sub rdi, rax
mov rax, rdi
ret
这似乎意味着:取num1和num2的差异,将其保存在rdi中。如果它&gt; 0,将diff放入rax,否则将rax保留为0.返回值为rdi-rax,它将为0或diff,具体取决于移动到rax的内容。所以,非常接近(num1 <= num2) * (num1 - num2)
- 只是用减法而不是乘法来完成:)
答案 1 :(得分:1)
这是由于编译器。该过程发生在第2阶段。
基本上用于优化的编译器设置a=num1-num2
并将其存储在其内存中。
所以现在它只计算了一次,只是将它放在声明中。
big = a - (n1>n2)*a;
这是big = a
或big = 0
,总共执行3次计算。一个用于num1-num2,另一个用于n1> n2,第三个用于(a-1 * a)或(a-0 * a)
另一个:
big = n1 - (n1>n2)*(n1-n2)
有以下内容:
前一个有3个计算,而这个有4个。 第一个时间会更好,特别是因为正在处理大数字,否则时差应该可以忽略不计。 另外,请注意,如果您反复运行时间测试,即使是您提到的两个计算之一,您也会看到所用时间的变化。所以请注意,你对时差的观察并不完全是绝对的,但是第一个会比第二个更快。
编辑1:另外,注意第一个语句if (n1>n2)
是假的,即0,那么它只是变成big = a - 0*a
,这里,编译器也不执行乘法,因为它看到0 in声明和多重操作数。之后它也不会执行减法并简单地在内存中写为big=a
,这样也可以提供更快的结果
if (n1>n2)
是真的,同样成立,big=a-1*a
编译器看到1
并在被乘数操作数中将其消除,然后只需写入就不需要执行乘法而只需将其写为a -a
。 main 部分,当它a-a
时,它首先被转换为位,然后在减法之后最终转换为00000,现在这些位不会被编译器再次转换回十进制0并且可以简单地写成0. 然而对于n1-()*(n1-n2)`,这个数字将变成负数,基本上在得到最终结果后,转换为十进制也将发生。