除以2哪一个更好的右移算子或传统的除法运算符?

时间:2014-05-08 06:15:13

标签: java bitwise-operators

在阅读Collections.reverse方法的Java源代码时,Right Shift operator is used for finding middle.

......
            for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--) // Right Shift 
                swap(list, i, j);
.....

使用传统的除以2的方法也可以做到这一点。

我在堆栈Right Shift to perform division上进行了探索,发现使用除法运算符更好,而不是右移。

更新But then why java guys used Right Shift and not division ?

So which approach is better to use and Why ?

4 个答案:

答案 0 :(得分:2)

使用更易读的选项总是更好,除非迫切需要速度。

选择明确,明显的划分,然后如果您发现自己需要稍后进行优化,则可以更改为正确的位置并进行清晰评论。

答案 1 :(得分:2)

2分右移,右移1分并不完全等效。划分为2轮,即使是负数。向右移1轮,这意味着-1 >> 1-1(而-1 / 2为零)。

具体来说,这意味着如果JIT编译器不能(或不能)证明某个数字不能为负数(如果您已发布完整代码,我可能已经能够检查它),那就必须这样做一个更复杂的东西,而不仅仅是一个正确的转变 - 这样的事情:(根据GCC输出将eax除以2和clobbers edi

mov edi, eax
shr eax, 31
add eax, edi
sar eax, 1

如果你使用了1的右移,那就像是

sar eax, 1

它不是的差异,但它 是一个区别,所以&#34;它没有任何区别&#34 ; -crowd现在可以回家了。好吧,它仅适用于循环初始化,因此它不会对性能产生严重影响,但我们不要忘记这是库代码 - 适用不同的指南。具体而言,可读性不那么强调,并且指南不会浪费性能,除非你绝对必须&#34;更加强调。在这种情况下,没有充分的理由在那里写size / 2,所有这一切都会使性能变得更糟。没有好处。

另外,在这种情况下,我觉得这个可读性有点傻。如果有人真的不知道size >> 1做了什么,那就是他们的问题 - 它只是一个基本的运算符,甚至不是一些错综复杂的组合运营商,如果你不能阅读它,那么你就不会了解Java。

但您可以在自己的代码中使用size / 2。从这个答案中得出的结论不应该是&#34;除以2是坏的&#34;,而是&#34; 库代码不应该为了可读性而牺牲性能&#34 34。

答案 2 :(得分:0)

在实践中它并不重要,但是一个师会使意图变得更清晰,我只能想象一个人会因为性能原因而试图进行比特转换。但是2014年你并没有手动编写x86程序集,因此尝试优化这样的代码是浪费时间。

答案 3 :(得分:0)

与除法运算符相比,右移运算符更快。 如您所知,所有数据都以二进制格式存储和处理。右移直接在二进制格式上工作,因此是快速和最佳的。除法适用于整数,因此很慢而且不是最优的。 但是,由于处理器速度现在相当不错,并且它并没有真正改变你使用哪个运算符,所以选择真的是你的。 如果您认为您的应用程序已经占用了太多的处理器速度而您真的觉得需要减轻负载,那么您可以使用右移。对于轻量级应用,除法运算符也适用。