Why does JDK use shifting instead of multiply/divide?

為{幸葍}努か 提交于 2020-06-11 20:57:49

问题


I have the following question:

If asked whether to use a shift vs a multiply or divide for example the answer would be, let the JVM optimize.

Example here: is-shifting-bits-faster-than-multiplying

Now I was looking at the jdk source, for example Priority Queue and the code uses only shifting for both multiplication and division (signed and unsigned).

Taking for granted that the post in SO is the valid answer I was wondering why in jdk they prefer to do it by shifting?

Is it some subtle detail unrelated to performance? I am suspecting it must have something to do with over/underflow multiplication and division but I am not sure.

Anyone has an idea? Are subtly overflow issues handled better using shifting? Or it is just a matter of taste?


回答1:


I think they do it in this specific example to use the sign bit. Java lacks unsigned types, so it is not possible to emulate a >>> 1 with a /= 2 for numbers that use the most significant bit. Note how the code uses only >>> throughout your example. I am reasonably certain that this is to get full use of the entire bit range.




回答2:


Apart from shift being faster than division on most systems. The >>> performs an unsigned operation, which division does not. e.g. if you want the mid point of two values, you need to use >>> to avoid an overflow. (See Arrays.binarySearch for similar code)




回答3:


Some valid reasons to prefer shifting in Java:

  • If there is a chance that you may be running in a non-optimised environment and you can't guarantee that the JIT compiler will make the necessary optimisation for you. This is probably rare nowadays, but could still happen in some circumstances.
  • If you are genuinely doing bit manipulations rather than numerical operations - it is more clear in the source code to use shifts directly
  • If you want unsigned operations (for example you can easily do unsigned shifts, but not unsigned divides)



回答4:


It is more a matter of taste. Some people are so used to binary operations that they are more native to them (I personally also use such in code I am writing for myself). However from performance point of view the two behave the same (the optimization happens compile-time so the use of shifts will improve the compile time, but with minor fraction and you can neglect that).

EDIT And as it happens often there is something new I learn from every answer I give: consider this. It proves why division by two can not always be optimized to shifting. So my above comment is almost completely wrong, as long as java does not have unsigned types.



来源:https://stackoverflow.com/questions/9247804/why-does-jdk-use-shifting-instead-of-multiply-divide

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!