Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is shifting bits faster than multiplying and dividing in Java? .NET? [closed]

People also ask

Is bit manipulation faster than multiplication?

On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition.

Is bit shifting faster than adding?

Bit-shifting is still faster, but for non-power-of-two mul/div by the time you do all your shifts and add the results it's slower again.

What is the purpose of bit shifting?

A bit shift is a bitwise operation where the order of several bits is moved, either to the left or right, to efficiently perform a mathematical operation. Bit shifts help with optimization in low-level programming because they require fewer calculations for the CPU than conventional math.

What is bit shifting multiplication?

Bitshifting shifts the binary representation of each pixel to the left or to the right by a pre-defined number of positions. Shifting a binary number by one bit is equivalent to multiplying (when shifting to the left) or dividing (when shifting to the right) the number by 2.


Almost any environment worth its salt will optimize this away for you. And if it doesn't, you've got bigger fish to fry. Seriously, do not waste one more second thinking about this. You will know when you have performance problems. And after you run a profiler, you will know what is causing it, and it should be fairly clear how to fix it.

You will never hear anyone say "my application was too slow, then I started randomly replacing x * 2 with x << 1 and everything was fixed!" Performance problems are generally solved by finding a way to do an order of magnitude less work, not by finding a way to do the same work 1% faster.


Most compilers today will do more than convert multiply or divide by a power-of-two to shift operations. When optimizing, many compilers can optimize a multiply or divide with a compile time constant even if it's not a power of 2. Often a multiply or divide can be decomposed to a series of shifts and adds, and if that series of operations will be faster than the multiply or divide, the compiler will use it.

For division by a constant, the compiler can often convert the operation to a multiply by a 'magic number' followed by a shift. This can be a major clock-cycle saver since multiplication is often much faster than a division operation.

Henry Warren's book, Hacker's Delight, has a wealth of information on this topic, which is also covered quite well on the companion website:

  • http://www.hackersdelight.org/

See also a discussion (with a link or two ) in:

  • Reading assembly code

Anyway, all this boils down to allowing the compiler to take care of the tedious details of micro-optimizations. It's been years since doing your own shifts outsmarted the compiler.


Humans are wrong in these cases.

99% when they try to second guess a modern (and all future) compilers.
99.9% when they try to second guess modern (and all future) JITs at the same time.
99.999% when they try to second guess modern (and all future) CPU optimizations.

Program in a way that accurately describes what you want to accomplish, not how to do it. Future versions of the JIT, VM, compiler, and CPU can all be independantly improved and optimized. If you specify something so tiny and specific, you lose the benefit of all future optimizations.


You can almost certainly depend on the literal-power-of-two multiplication optimisation to a shift operation. This is one of the first optimisations that students of compiler construction will learn. :)

However, I don't think there's any guarantee for this. Your source code should reflect your intent, rather than trying to tell the optimiser what to do. If you're making a quantity larger, use multiplication. If you're moving a bit field from one place to another (think RGB colour manipulation), use a shift operation. Either way, your source code will reflect what you are actually doing.


Note that shifting down and division will (in Java, certainly) give different results for negative, odd numbers.

int a = -7;
System.out.println("Shift: "+(a >> 1));
System.out.println("Div:   "+(a / 2));

Prints:

Shift: -4
Div:   -3

Since Java doesn't have any unsigned numbers it's not really possible for a Java compiler to optimise this.


On computers I tested, integer divisions are 4 to 10 times slower than other operations.

When compilers may replace divisions by multiples of 2 and make you see no difference, divisions by not multiples of 2 are significantly slower.

For example, I have a (graphics) program with many many many divisions by 255. Actually my computation is :

r = (((top.R - bottom.R) * alpha + (bottom.R * 255)) * 0x8081) >> 23;

I can ensure that it is a lot faster than my previous computation :

r = ((top.R - bottom.R) * alpha + (bottom.R * 255)) / 255;

so no, compilers cannot do all the tricks of optimization.